<script lang="tsx" setup>
import { isMockDevelopment } from '@/config'
import { scrollbarProps, type InputInst } from 'naive-ui'
import { useRouter } from 'vue-router'
import { UAParser } from 'ua-parser-js'
import TableModal from './TableModal.vue'
import DefaultPage from './DefaultPage.vue'
import SuggestedView from './SuggestedPage.vue'
import MyappLications from './MyappLications.vue'
import knowledgeList from './knowledgeList.vue'
import setting from './setting.vue'
import { NButton, NTag, useMessage ,NDropdown,NIcon,NTooltip,NCard} from 'naive-ui'
import { useBusinessStore } from '@/store/business'
const route = useRoute()
const router = useRouter()
const message = useMessage()
import * as GlobalAPI from '@/api'
import { pad } from 'lodash-es'
import { resolve } from 'path'
import { color } from 'echarts'
import { download } from 'naive-ui/es/_utils'
import { json } from 'stream/consumers'

const baseUrl = import.meta.env.VITE_APP_BASE_API
const viewerOptions = {
  inline: false,
  button: true,
  navbar: false,
  title: false,
  toolbar: {
    zoomIn: true,
    zoomOut: true,
    oneToOne: true,
    reset: true,
    prev: false,
    next: false,
    rotateLeft: true,
    rotateRight: true,
    flipHorizontal: true,
    flipVertical: true,
  },
  tooltip: true,
  movable: true,
  zoomable: true,
  rotatable: true,
  scalable: true,
  transition: true,
}

// 显示默认页面
const showDefaultPage = ref(true)

//全局存储
const businessStore = useBusinessStore()

//是否是刚登录到系统 批量渲染对话记录
const isInit = ref(false)

// 添加一个新的响应式变量来控制显示哪个组件
const showAppMarketplace = ref('chat')

// 切换显示应用广场组件
const toggleAppMarketplace = (value) => {
    showAppMarketplace.value=value
    conversationList.chatId=''
    localStorage.removeItem('chatId')
    conversationList.title=''
    localStorage.removeItem('title')
    conversationList.conversationId=''
    localStorage.removeItem('conversationId')
    showDefaultPage.value = true
//   showAppMarketplace.value = !showAppMarketplace.value
  // 如果切换回聊天界面，重置一些状态
  if (!showAppMarketplace.value) {
    // 可以在这里添加一些重置逻辑
  }
}
const AppName=ref('')
const AppDescription=ref('')
const AppIcon=ref('')
const AppIconType=ref('')
const AppIconBackground=ref('')
const hasAppModel=ref(false)
const isCommQa=ref(true)
const showAppIcon=ref(false)
const selectApp=(item)=>{
    console.log('item',item)
    // hasAppModel.value=true
    showAppMarketplace.value='chat'
    conversationList.chatId=item.chatId
    conversationList.title=item.name
    AppName.value=item.name
    AppDescription.value=item.description
    AppIcon.value=item.icon
    AppIconBackground.value=item.iconBackground
    AppIconType.value=item.iconType
    conversationList.conversationId=item.conversationId
    isCommQa.value=item.isCommQa
    appId.value=item.id
    fetchAPPData()
    // localStorage.setItem('chatId',item.chatId)
}
// const appId=ref('71f10af9-f92e-4b12-bb65-635630418653')

const appId=ref('42ad97ed-7bba-46a4-ab37-ef1780b20e78')
const transcript=ref('')

// const appId=ref('47134080-ca04-40ce-9286-7e9a584baafd')
// 使用 onMounted 生命周期钩子加载历史对话
onMounted(() => {
    fetchConversationHistory(
        isInit,
        conversationItems,
        tableData,
        currentRenderIndex
    )
   // 在已有的 onMounted 函数中添加这段代码
   const savedState = localStorage.getItem('sidebarCollapsed')
    if (savedState !== null) {
        sidebarCollapsed.value = savedState === 'true'
    }
  if(localStorage.getItem('chatId')){
    getUserDetail(localStorage.getItem('chatId'))
    console.log('localStorage.getItem',typeof localStorage.getItem('chatId'))
    conversationList.chatId = Number(localStorage.getItem('chatId'))
    
  }
  fetchResultData()
  fetchAPPData()
  // if ('webkitSpeechRecognition' in window|| 'SpeechRecognition' in window) {
  //    recognition.value = new SpeechRecognition()
  // recognition.value.lang = 'zh-CN' // 可换成 en-US
  // recognition.value.continuous = false
  // recognition.value.interimResults = false

  //   recognition.value.onresult = (event) => {
  //     const transcript = event.results[0][0].transcript
  //     console.log('transcript', transcript)
  //     transcript.value = transcript
  //     inputTextString.value = transcript
  //     if (refInputTextString.value) {
  //       refInputTextString.value.focus()
  //       // refInputTextString.value.updateValue(inputTextString.value)
  //     }
  //     isRecording.value = false
  //   }

  //   recognition.value.onerror = (event) => {
  //     console.error('语音识别错误:', event.error)
  //     isRecording.value = false
  //   }
  // }

  // 初始化 SpeechRecognition
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
  recognition.value = new SpeechRecognition()
  recognition.value.lang = 'zh-CN' // 可换成 en-US
  recognition.value.continuous = false
  recognition.value.interimResults = false

  recognition.value.onresult = (event) => {
    transcript.value = event.results[0][0].transcript
    inputTextString.value = event.results[0][0].transcript
  }

  recognition.value.onerror = (event) => {
    console.error('语音识别错误:', event)
  }
} else {
  alert('当前浏览器不支持 Web Speech API')
}
const container = messagesContainer.value
  if (container) {
    container.addEventListener('scroll', checkScrollPosition)
  }

})
// 在 onUnmounted 中移除监听
onUnmounted(() => {
  const container = messagesContainer.value
  if (container) {
    container.removeEventListener('scroll', checkScrollPosition)
  }
})
//管理对话
const isModalOpen = ref(false)
function openModal() {
    isModalOpen.value = true
}
//模态框关闭
function handleModalClose(value) {
    isModalOpen.value = value
    //重新加载对话记录
    fetchConversationHistory(
        isInit,
        conversationItems,
        tableData,
        currentRenderIndex
    )
}

//新建对话
function newChat() {
    if (showDefaultPage.value) {
        window.$ModalMessage.success(`已经是最新对话`)
        
    }
    showDefaultPage.value = true
    isInit.value = false
    conversationItems.value = []
    stylizingLoading.value = false
    suggested_array.value = []
    conversationList.conversationId=''
    localStorage.removeItem('conversationId')
    conversationList.chatId=''
    showAppMarketplace.value='chat'
    onAqtiveChange('COMMON_QA')
    localStorage.removeItem('chatId')
    localStorage.removeItem('title')

    // AppName.value=''

}

/**
 * 默认大模型
 */
const defaultLLMTypeName = 'qwen2'
const currentChatId = computed(() => {
    return route.params.chatId
})

//主页面加载提示
const loading = ref(true)
setTimeout(() => {
    loading.value = false
})

//对话等待提示词图标
const stylizingLoading = ref(false)

//输入字符串
const inputTextString = ref('')
const refInputTextString = ref<InputInst | null>()

//输出字符串 Reader 流（风格化的）
const outputTextReader = ref<ReadableStreamDefaultReader | null>()

//markdown对象
const refReaderMarkdownPreview = ref<any>()

//主内容区域
const messagesContainer = ref<HTMLElement | null>(null)
// 添加语音识别相关的响应式变量
const isRecording = ref(false)
const recognition = ref(null)
// 切换语音识别状态
const toggleRecording = () => {
  if (!recognition.value) {
    window.$message.error('您的浏览器不支持语音识别功能')
    return
  }

  if (isRecording.value) {
    recognition.value.stop()
    isRecording.value = false
  } else {
    try {
      recognition.value.start()
      isRecording.value = true
      console.log('开始语音识别')
    } catch (error) {
      console.error('启动语音识别失败:', error)
      window.$message.error('启动语音识别失败，请检查麦克风权限')
      isRecording.value = false
    }
  }
}
//读取失败
const onFailedReader = (index: number) => {
    if (conversationItems.value[index]) {
        conversationItems.value[index].reader = null
        stylizingLoading.value = false
        if (refReaderMarkdownPreview.value) {
            refReaderMarkdownPreview.value.initializeEnd()
        }
        window.$ModalMessage.error('请求失败，请重试')
        setTimeout(() => {
            if (refInputTextString.value) {
                refInputTextString.value.focus()
            }
        })
    }
}

//读取完成
const onCompletedReader = (index: number) => {
    console.log('onCompletedReader', index)
    if (conversationItems.value[index]) {
        stylizingLoading.value = false
        setTimeout(() => {
            if (refInputTextString.value) {
                refInputTextString.value.focus()
            }
        })
            
        // 在这里更新侧边栏对话列表
        // 使用 setTimeout 确保后端有足够时间处理数据
     
    
        fetchData().then((res) => {
            console.log('reslocal', localStorage.getItem('chatId'))
           conversationList.chatId=Number(localStorage.getItem('chatId'))
        //    conversationList.title=res[0]['今天'][0]['title']
        //    conversationList.conversationId=res[0]['今天'][0]['conversationId']
        })
        uploadedFiles.value = []
        previewImage.value = ''
        file_name.value = ''
        businessStore.update_file_url('')
    }

    // 查询是推荐列表
    // query_dify_suggested()
}

//当前索引位置
const currentRenderIndex = ref(0)
//图表子组件渲染完毕
const onChartReady = (index) => {
    if (index < conversationItems.value.length) {
        // console.log('onChartReady', index)
        currentRenderIndex.value = index
        stylizingLoading.value = false
    }
}

const onRecycleQa = async (index: number) => {
    //设置当前选中的问答类型
    const item = conversationItems.value[index]
    onAqtiveChange(item.qa_type)

    if (item.qa_type == 'FILEDATA_QA') {
        businessStore.update_file_url(item.file_key)
    }

    // 清空推荐列表
    suggested_array.value = []
    //发送问题重新生成
    handleCreateStylized(item.question)
    scrollToBottom()
}

//赞 结果反馈
const onPraiseFeadBack = async (index:number) => {
    console.log('onPraiseFeadBack', index)

    const item = conversationItems.value[index]
    console.log('onPraiseFeadBack', item)

    item.rating===1? item.rating=0: item.rating=1
    if(item.rating===-1){
        item.rating=1
    }
    const res = await GlobalAPI.fead_back(item.chat_id, item.rating)
    if (res.ok) {
        window.$ModalMessage.destroyAll()
        window.$ModalMessage.success('感谢反馈', {
            duration: 1500
        })
    }
}

//开始输出时隐藏加载提示
const onBeginRead = async (index: number) => {
    //设置最上面的滚动提示图标隐藏
    contentLoadingStates.value[currentRenderIndex.value - 1] = false
}

//踩 结果反馈
const onBelittleFeedback = async (index: number) => {
    const item = conversationItems.value[index]
    item.rating===-1? item.rating=0: item.rating=-1
    if(item.rating===1){
        item.rating=-1
    }

    const res = await GlobalAPI.fead_back(item.chat_id, item.rating)
    if (res.ok) {
        window.$ModalMessage.destroyAll()
        window.$ModalMessage.success('感谢反馈', {
            duration: 1500
        })
    }
}

// 侧边栏对话历史
interface TableItem {
    index: number
    key: string
}
const tableData = ref<TableItem[]>([])
const tableRef = ref(null)
const tableAppData=ref([])
//保存对话历史记录
const conversationItems = ref<
    Array<{
        chat_id: string
        qa_type: string
        question: string
        file_key: string
        role: 'user' | 'assistant',
        rating: number,
        file_name:string,
        file_size:string,
        file_url:string,
        reader: ReadableStreamDefaultReader | null
    }>
>([])

// 这里子组件 chart渲染慢需要子组件渲染完毕后通知父组件
const visibleConversationItems = computed(() => {
    return conversationItems.value.slice(0, currentRenderIndex.value + 2)
})
//这里控制内容加载状态
const contentLoadingStates = ref(
    visibleConversationItems.value.map(() => false)
)

// watch(
//     currentRenderIndex,
//     (newValue, oldValue) => {
//         console.log('currentRenderIndex 新值:', newValue)
//         console.log('currentRenderIndex 旧值:', oldValue)
//     },
//     { immediate: true }
// )

// watch(
//     conversationItems,
//     (newValue, oldValue) => {
//         console.log('visibleConversationItems 新值:', newValue)
//         console.log('visibleConversationItems 旧值:', oldValue)
//     },
//     { immediate: true }
// )

// chat_id定义
const uuid = ref('')
const getLatestFeadId = async () => {
    // 等待一小段时间，确保 feadId 已被设置
    await new Promise(resolve => setTimeout(resolve, 3000));
    return localStorage.getItem('feadId') || uuid.value;
}
//提交对话
const handleCreateStylized = async (send_text = '') => {
    console.log('send_text', send_text)
  
    // 滚动到底部
    scrollToBottom()

    //设置初始化数据标识为false
    isInit.value = false

    //清空推荐列表
    suggested_array.value = []

    // 若正在加载，则点击后恢复初始状态
    if (stylizingLoading.value) {
        onCompletedReader(conversationItems.value.length - 1)
        return
    }
   
    //如果输入为空，则直接返回
    if (send_text == '') {
        if (refInputTextString.value && !inputTextString.value.trim()) {
            inputTextString.value = ''
            refInputTextString.value.focus()
            return
        }
    }

    //如果没有上传文件 表格问答直接提示并返回
    // if (
    //     qa_type.value == 'FILEDATA_QA' &&
    //     `${businessStore.$state.file_url}` === ''
    // ) {
    //     window.$ModalMessage.success('请先上传文件')
    //     return
    // }

    if (showDefaultPage.value) {
        // 新建对话 时输入新问题 清空历史数据
        conversationItems.value = []
        showDefaultPage.value = false
    }
// console.log(file_name.value,'file_name.value')

    // if( file_name !== '') {
    //     // 若上传文件 则发送文件名
    //     send_text = file_name.value+send_text
    // }
    //加入对话历史用于左边表格渲染
    const newItem = {
        index: tableData.value.length, // 或者根据你的需求计算新的索引
        key: inputTextString.value ? inputTextString.value : send_text
    }
    // 使用 unshift 方法将新元素添加到数组的最前面
    tableData.value.unshift(newItem)
    //调用大模型后台服务接口
    stylizingLoading.value = true
    const textContent = inputTextString.value
        ? inputTextString.value
        : send_text
    inputTextString.value = ''
    let file_name=''
    let file_size=''
    let file_url=''
    let saveFiles=JSON.parse(JSON.stringify(uploadedFiles.value))
    if(uploadedFiles.value.length>0){
        file_name=saveFiles[0].name
        file_size=saveFiles[0].size
        file_url=file_urlList.value
    }
    console.log('previewImage',previewImage.value)
    if(previewImage.value){
 console.log('previewImage',previewImage.value)
        file_url=previewImage.value 
    }
    if (textContent) {
        // 存储该轮用户对话消息
        conversationItems.value.push({
            chat_id: uuid.value,
            qa_type: qa_type.value,
            question: textContent,
            file_key: '',
            role: 'user',
            rating: 0,
            file_name:file_name,
            file_size:file_size,
            file_url:file_url,
            reader: null
        })
        // 更新 currentRenderIndex 以包含新添加的项
        currentRenderIndex.value = conversationItems.value.length - 1
        contentLoadingStates.value[currentRenderIndex.value] = true
    }
    uploadedFiles.value = []
    previewImage.value = ''
    uuid.value = uuidv4()
    let conversationId=conversationList.conversationId|| localStorage.getItem('conversationId')||''
    let chatId=conversationList.chatId||localStorage.getItem('chatId ')||''

    const { error, reader, needLogin ,feadId} =
        await businessStore.createAssistantWriterStylized(
            uuid.value,
            currentChatId.value,
            {
                text: textContent,
                writer_oid: currentChatId.value,
                chatId:chatId,
                conversationId:conversationId,
                appId:appId.value,
                fileUrl:file_url?file_url:"",
                fileSize:saveFiles[0]?saveFiles[0].size:"",
                fileKey:saveFiles[0]?saveFiles[0].name:"",
                uploadFileId:uploadFileId.value,
                qaType: qa_type.value,
                "type": getFileType(qa_type.value),
         

            }
        )
console.log('reader', reader)
// uploadedFiles.value = []
    if (needLogin) {
        message.error('登录已失效，请重新登录')

        //跳转至登录页面
        setTimeout(() => {
            router.push('/login')
        }, 2000)
    }

    if (error) {
        stylizingLoading.value = false
        onCompletedReader(conversationItems.value.length - 1)
        return
    }
   console.log('reader', reader)
   const chatId1 = await getLatestFeadId();
   console.log('feadIdfeadIdfeadIdfeadId', chatId1)

    if (reader) {
        outputTextReader.value = reader
        // 存储该轮AI回复的消息
      
        console.log('feadIdfeadIdfeadIdfeadId', chatId)
        conversationItems.value.push({
            chat_id: chatId1,
            qa_type: qa_type.value,
            question: textContent,
            file_key: `${businessStore.$state.file_url}`,
            role: 'assistant',
            rating: 0,
            reader: reader
        })
        // 更新 currentRenderIndex 以包含新添加的项
        currentRenderIndex.value = conversationItems.value.length - 1
       
    }
    
setTimeout(()=>{
    conversationItems.value.forEach((item, index) => {
      if(item.chat_id==chatId1){
        item.chat_id=localStorage.getItem('feadId')
       
      }
    })

  
    console.log('conversationItems',conversationItems)
    console.log( localStorage.getItem('feadId'),'loclallllllllllll',chatId1)
},1000)
    // 滚动到底部
    scrollToBottom()
}

const shouldShowScrollButton = ref(false)

// 添加监听滚动事件的函数
const checkScrollPosition = () => {
  const container = messagesContainer.value
  if (!container) return
  
  // 检查是否有内容被输入框遮挡
  const scrollHeight = container.scrollHeight
  const scrollTop = container.scrollTop
  const clientHeight = container.clientHeight
  
  // 如果有内容被遮挡（距离底部超过100px）且不在底部，则显示按钮
  shouldShowScrollButton.value = (scrollHeight - scrollTop - clientHeight) > 100
}


// 滚动到底部
const scrollToBottom = () => {
    nextTick(() => {
        if (messagesContainer.value) {
            messagesContainer.value.scrollTop =
                messagesContainer.value.scrollHeight
        }
    })
}

const keys = useMagicKeys()
const enterCommand = keys['Enter']
const enterCtrl = keys['Enter']

const activeElement = useActiveElement()
const notUsingInput = computed(
    () => activeElement.value?.tagName !== 'TEXTAREA'
)

const parser = new UAParser()
const isMacos = parser.getOS().name.includes('Mac')

const placeholder = computed(() => {
    if (stylizingLoading.value) {
        return `输入任意问题...`
    }
    return `输入任意问题, 按 ${
        isMacos ? 'Command' : 'Ctrl'
    } + Enter 键快捷开始...`
})

const generateRandomSuffix = function () {
    return Math.floor(Math.random() * 10000) // 生成0到9999之间的随机整数
}

watch(
    () => enterCommand.value,
    () => {
        if (!isMacos || notUsingInput.value) return

        if (stylizingLoading.value) return

        if (!enterCommand.value) {
            handleCreateStylized()
        }
    },
    {
        deep: true
    }
)

watch(
    () => enterCtrl.value,
    () => {
        if (isMacos || notUsingInput.value) return

        if (stylizingLoading.value) return

        if (!enterCtrl.value) {
            handleCreateStylized()
        }
    },
    {
        deep: true
    }
)

//重置状态
const handleResetState = () => {
    if (isMockDevelopment) {
        inputTextString.value = ''
    } else {
        inputTextString.value = ''
    }

    stylizingLoading.value = false
    nextTick(() => {
        refInputTextString.value?.focus()
    })
    refReaderMarkdownPreview.value?.abortReader()
    refReaderMarkdownPreview.value?.resetStatus()
}
handleResetState()

//文件上传
// let file_name = ref('')
// const finish_upload = (res) => {
//     file_name.value = res.file.name
//     if (res.event.target.responseText) {
//         let json_data = JSON.parse(res.event.target.responseText)
//         let file_url = json_data['data']['object_key']
//         if (json_data['code'] == 200) {
//             onAqtiveChange('FILEDATA_QA')
//             businessStore.update_file_url(file_url)
//             window.$ModalMessage.success(`文件上传成功`)
//         } else {
//             window.$ModalMessage.error(`文件上传失败`)
//             return
//         }
//         var query_text = file_name.value + ' 总结归纳文档的关键信息'
//         handleCreateStylized(query_text)
//     }
// }

// 下面方法用于左侧对话列表点击 右侧内容滚动
// 用于存储每个 MarkdownPreview 容器的引用
const markdownPreviews = ref<Array<HTMLElement | null>>([]) // 初始化为空数组

// 表格行点击事件
const rowProps = (row: any) => {
    return {
        onClick: () => {
            suggested_array.value = []
            // 这里*2 是因为对话渲染成两个
            if (tableData.value.length * 2 != conversationItems.value.length) {
                fetchConversationHistory(
                    isInit,
                    conversationItems,
                    tableData,
                    currentRenderIndex
                )
            }

            if (row.index == tableData.value.length - 1) {
                if (conversationItems.value.length === 0) {
                    fetchConversationHistory(
                        isInit,
                        conversationItems,
                        tableData,
                        currentRenderIndex
                    )
                }
                //关闭默认页面
                showDefaultPage.value = false
                scrollToBottom()
            } else {
                if (row.index == 0) {
                    scrollToItem(0)
                } else if (row.index < 2) {
                    scrollToItem(row.index + 1)
                } else {
                    scrollToItem(row.index + 2)
                }
            }
        }
    }
}

// 设置 markdownPreviews 数组中的元素
const setMarkdownPreview = (index: number, el: any) => {
    if (el && el instanceof HTMLElement) {
        // 确保 markdownPreviews 数组的长度与 visibleConversationItems 的长度一致
        if (index >= markdownPreviews.value.length) {
            markdownPreviews.value.push(null)
        }
        markdownPreviews.value[index] = el
    } else if (el && el.value && el.value instanceof HTMLElement) {
        // 处理代理对象的情况
        if (index >= markdownPreviews.value.length) {
            markdownPreviews.value.push(null)
        }
        markdownPreviews.value[index] = el.value
    }
}

// 滚动到指定位置的方法
const scrollToItem = (index: number) => {
    //判断默认页面是否显示或对话历史是否初始化
    //(!showDefaultPage.value && !isInit.value) ||
    if (conversationItems.value.length === 0) {
        // console.log('fetchConversationHistory')
        fetchConversationHistory(
            isInit,
            conversationItems,
            tableData,
            currentRenderIndex
        )
    }

    //关闭默认页面
    showDefaultPage.value = false
    if (markdownPreviews.value[index]) {
        markdownPreviews.value[index].scrollIntoView({
            behavior: 'smooth',
            block: 'start',
            inline: 'nearest'
        })
    }
}

//默认选中的对话类型
const qa_type = ref('COMMON_QA')
const onAqtiveChange = (val) => {
    qa_type.value = val
    businessStore.update_qa_type(val)

    //清空文件上传历史url
    if (val == 'FILEDATA_QA') {
        businessStore.update_file_url('')
    }
}

//获取建议问题
const suggested_array = ref([])
const query_dify_suggested = async () => {
    if (!isInit.value) {
        const res = await GlobalAPI.dify_suggested(uuid.value)
        const json = await res.json()
        if (json?.data?.data !== undefined) {
            suggested_array.value = json.data.data
        }
    }

    // 滚动到底部
    scrollToBottom()
}
// 建议问题点击事件
const onSuggested = (index: number) => {
    // 如果是报告问答的建议问题点击后切换到通用对话
    if (qa_type.value == 'REPORT_QA') {
        onAqtiveChange('COMMON_QA')
    }
    handleCreateStylized(suggested_array.value[index])
}

// 下拉菜单的选项
const options = [
    {
        label: () => h('span', null, '上传文档'),
        icon: () =>
            h('div', {
                class: 'i-vscode-icons:file-type-excel2',
                style: 'inline-block:none'
            }),
        key: 'excel'
    },
    {
        label: () => h('span', null, '上传图片'),
        icon: () =>
            h('div', {
                class: 'i-vscode-icons:file-type-image',
                style: 'inline-block:none'
            }),
        key: 'image'
    }
]

// 下拉菜单选项选择事件处理程序
const uploadRef = ref<HTMLElement | null>(null)
const uploadImgRef = ref<HTMLElement | null>(null)

function handleSelect(key: string) {
    if (key === 'excel') {
        // 使用 nextTick 确保 DOM 更新完成后执行
        nextTick(() => {
            if (uploadRef.value) {
                // 尝试直接调用 n-upload 的点击方法
                // 如果 n-upload 没有提供这样的方法，可以查找内部的 input 并调用 click 方法
                const fileInput =
                    uploadRef.value.$el.querySelector('input[type="file"]')
                if (fileInput) {
                    fileInput.click()
                }
            }
        })
    } else {
        // window.$ModalMessage.success('功能开发中', {
        //     duration: 1500
        // })
        nextTick(() => {
            if (uploadImgRef.value) {
                // 尝试直接调用 n-upload 的点击方法
                // 如果 n-upload 没有提供这样的方法，可以查找内部的 input 并调用 click 方法
                const fileInput =
                uploadImgRef.value.$el.querySelector('input[type="file"]')
                if (fileInput) {
                    fileInput.click()
                }
            }
        })
   
    }
}

// 侧边表格滚动条数 动态显示隐藏设置
const scrollableContainer = ref(null)
const showScrollbar = () => {
    if (
        scrollableContainer.value &&
        scrollableContainer.value.$el &&
        scrollableContainer.value.$el.firstElementChild
    ) {
        scrollableContainer.value.$el.firstElementChild.style.overflowY = 'auto'
    }
}

const hideScrollbar = () => {
    if (
        scrollableContainer.value &&
        scrollableContainer.value.$el &&
        scrollableContainer.value.$el.firstElementChild
    ) {
        scrollableContainer.value.$el.firstElementChild.style.overflowY =
            'hidden'
    }
}

// 侧边栏折叠状态
const sidebarCollapsed = ref(false)

// 切换侧边栏状态
const toggleSidebar = () => {
    sidebarCollapsed.value = !sidebarCollapsed.value
    // 可以选择将状态保存到 localStorage，以便在页面刷新后保持状态
    localStorage.setItem('sidebarCollapsed', sidebarCollapsed.value)
}

// 在 script 部分的 setup 函数中添加
const showSearchModal = ref(false)

// 打开搜索弹框
const openSearchModal = () => {
  showSearchModal.value = true
}

// 关闭搜索弹框
const closeSearchModal = () => {
    console.log('closeSearchModal')
  showSearchModal.value = false
  searchKeyword.value = ''
  searchResults.value = []
} 
const closeSearchModalL = () => {
    console.log('closeSearchModal')
  showSearchModal.value = false
  searchKeyword.value = ''
  searchResults.value = []
  fetchResultData()
} 

// 搜索关键词
const searchKeyword = ref('')

// 执行搜索
const performSearch = () => {
    console.log('searchKeyword.value', searchKeyword.value)
  if (!searchKeyword.value.trim()) {
    window.$ModalMessage.warning('请输入搜索关键词')
    return
  }

            GlobalAPI.search_user_record(searchKeyword.value).then(res => {
                if (res.ok) {
                    console.log(res,'res.json()')
                    return res.json();
                }
                throw new Error('获取对话历史失败');
            }).then(data => {
                console.log('data12333', data)
                if (data ) {
                    // 更新 tableData
                    searchResults.value = data;

                }
            }).catch(err => {
                console.error('更新对话历史失败:', err);
            });
     
  // 这里实现搜索逻辑
  console.log('搜索关键词:', searchKeyword.value)
  
//   // 模拟搜索结果，实际项目中应该调用API
//   searchResults.value = tableData.value.filter(item => 
//     item.key.toLowerCase().includes(searchKeyword.value.toLowerCase())
//   )
}

const isClearing = ref(false)

const handleInputUpdate = (value) => {
  // 如果不是通过清除按钮触发的输入更新，才执行搜索
  if (!isClearing.value) {
    performSearch()
  }
  // 重置标志
  isClearing.value = false
}

// 清空搜索结果
const performClear = () => {
    console.log('清空搜索结果')
    isClearing.value = true
  searchResults.value = []

}

// 搜索结果
const searchResults = ref([])

// 点击搜索结果项
// const handleSearchResultClick = (row) => {
//     // 这里添加加载对话内容的逻辑
//   showDefaultPage.value = false;
//   conversationList.conversationId = row.conversationId;
//   conversationList.chatId = row.chatId;
//   appId.value = row.appId;
//   localStorage.setItem('chatId', row.chatId);
//     getUserDetail(row.chatId)

// //   rowProps(row).onClick()
//   closeSearchModal()
// }
// 点击搜索结果项
const handleSearchResultClick = (row) => {
  // 这里添加加载对话内容的逻辑
  showDefaultPage.value = false;
  conversationList.conversationId = row.conversationId;
  conversationList.chatId = row.chatId;
  appId.value = row.appId;
  localStorage.setItem('chatId', row.chatId);
  getUserDetail(row.chatId);
  
  // 关闭搜索弹窗
  closeSearchModal();
  
  // 在左侧列表中查找并高亮对应的对话
  nextTick(() => {
    // 延迟执行，确保DOM已更新
    setTimeout(() => {
      // 查找所有对话组元素
      const groupElements = document.querySelectorAll('.n-data-table-wrapper');
      let found = false;
      
      // 遍历所有对话组
      groupElements.forEach(groupEl => {
        if (found) return;
        
        // 获取该组内所有对话项
        const conversationEls = groupEl.querySelectorAll('.table-cell-wrapper');
        
        // 遍历对话项
        conversationEls.forEach(convEl => {
          // 获取对话项的chatId
          const chatId = convEl.getAttribute('dataid');
          console.log(convEl,'convEl')
          // 如果找到匹配的chatId
          if (chatId == row.chatId) {
            found = true;
            
            // 滚动到该元素
            convEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
            showAppMarketplace.value='chat'
            // 添加高亮效果
            // document.querySelectorAll('.conversation-item').forEach(el => {
            //   el.classList.remove('highlight-conversation');
            // });
            // convEl.classList.add('highlight-conversation');
            
            // 3秒后移除高亮效果
            setTimeout(() => {
              convEl.classList.remove('highlight-conversation');
            }, 3000);
          }
        });
      });
      
      // 如果没有找到匹配的对话项，尝试通过内容匹配
      if (!found) {
        // 获取所有对话项
        const allConversationItems = document.querySelectorAll('.custom-table tr');
        
        allConversationItems.forEach(item => {
          if (item.textContent.includes(row.title)) {
            // 滚动到该元素
            item.scrollIntoView({ behavior: 'smooth', block: 'center' });
            
            // 添加高亮效果
            allConversationItems.forEach(el => {
              el.classList.remove('highlight-conversation');
            });
            item.classList.add('highlight-conversation');
            
            // 3秒后移除高亮效果
            setTimeout(() => {
              item.classList.remove('highlight-conversation');
            }, 3000);
            
            found = true;
          }
        });
      }
    }, 500); // 延迟500ms执行，确保DOM已完全更新
  });
}
const titleName=ref('')
// 添加对话历史数据结构
const conversationGroups = ref([
  {
    "今天": [
      {
        "chatId": 18,
        "conversationId": "c6990e8c-4e92-449c-afef-fb91633c1a7e",
        "createBy": "System",
        "createTime": "2025-05-14 14:55:03",
        "enable": true,
        "title": "请简单介绍下Java",
        "updateBy": "System",
        "updateTime": "2025-05-14 14:55:03",
        "userId": 1
      }
    ]
  },
  {
    "本周": []
  },
  {
    "本月": [
      {
        "chatId": 17,
        "conversationId": "0d73261f-6c0a-4d36-a59a-84b38d0fec19",
        "createBy": "System",
        "createTime": "2025-05-06 09:50:59",
        "enable": true,
        "title": "你好",
        "updateBy": "System",
        "updateTime": "2025-05-06 09:50:59",
        "userId": 1
      }
    ]
  },
  {
    "今年": [
      {
        "chatId": 16,
        "conversationId": "2efa14b3-65fd-458e-8972-bc135599a6bd",
        "createBy": "System",
        "createTime": "2025-04-25 16:57:30",
        "enable": true,
        "title": "2024",
        "updateBy": "System",
        "updateTime": "2025-04-25 16:57:30",
        "userId": 1
      },
      {
        "chatId": 15,
        "conversationId": "10982053-e1e9-4aca-a603-02f8bd19f766",
        "createBy": "System",
        "createTime": "2025-04-25 16:53:17",
        "enable": true,
        "title": "你好",
        "updateBy": "System",
        "updateTime": "2025-04-25 16:53:17",
        "userId": 1
      }
    ]
  },
  {
    "更久之前": []
  }
]);
const conversationList=reactive({conversationId:'',chatId:'',title:''})
// 处理对话项点击
const handleConversationClick = (conversation,choose) => {
  // hasAppModel.value = true;
  // isCommQa.value = true;
  if(choose){
       hasAppModel.value = false;
       isCommQa.value = true;
  }
  console.log('选择对话:', conversation);
  // 这里添加加载对话内容的逻辑
  showDefaultPage.value = false;
  conversationList.title = conversation.title;
  titleName.value = conversation.title;
  conversationList.conversationId = conversation.conversationId;
  showAppMarketplace.value='chat'
  conversationList.chatId = conversation.chatId;
  appId.value = conversation.appId;
  getUserDetail(conversation.chatId)
  // 根据 conversation 的 conversationId 加载对话内容
  if (conversation.conversationId) {
    // 这里可以调用 API 加载具体对话内容
    console.log('加载对话:', conversation.conversationId);
  }
  localStorage.setItem('chatId', conversation.chatId);
//   localStorage.setItem('conversationId', conversation.conversationId);
  localStorage.setItem('title', conversation.title);
}

const updateTitle = (newTitle) => {
  console.log('更新标题:', newTitle);
  conversationList.title = newTitle;
  fetchData()
  fetchAPPData()
}
const deleteConvsersation=(ref)=>{
  console.log('删除对话:', ref);
   fetchData()
   fetchAPPData()
   newChat()
}
// 处理更多操作
const handleMoreAction = (key, conversation) => {
  console.log('操作:', key, conversation);
  if (key === 'delete') {
    // 打开删除确认对话框
    openDeleteModal(conversation);
  } else if (key === 'edit') {
    // 打开编辑对话框
    openEditModal(conversation);
  }
}

// 添加删除对话框相关状态
const showDeleteModal = ref(false);
const currentConversation = ref(null);

// 打开删除确认对话框
const openDeleteModal = (conversation) => {
  currentConversation.value = conversation;
  console.log('打开删除确认对话框:', conversation);
  showDeleteModal.value = true;
}

// 关闭删除确认对话框
const closeDeleteModal = () => {
  showDeleteModal.value = false;
}

// 确认删除
const  confirmDelete = async() => {
  console.log('确认删除对话:', currentConversation.value.chatId);
    const res = await GlobalAPI.delete_user_record(currentConversation.value.chatId)
    if (res.ok) {
        fetchData()
        fetchAPPData()
        window.$ModalMessage.success(`删除成功`)
   if(currentConversation.value.chatId===Number(localStorage.getItem('chatId'))){
    showDefaultPage.value = true
    isInit.value = false
    conversationItems.value = []
    stylizingLoading.value = false
    suggested_array.value = []
    conversationList.conversationId=''
    localStorage.removeItem('conversationId')
    conversationList.chatId=''
    showAppMarketplace.value='chat'
    localStorage.removeItem('chatId ')
   }
    }
  // 这里添加实际的删除逻辑
  closeDeleteModal();
}

// 添加编辑对话框相关状态
const showEditModal = ref(false);
const editingTitle = ref('');

// 打开编辑对话框
const openEditModal = (conversation) => {
  currentConversation.value = conversation;
  editingTitle.value = conversation.title || '';
  showEditModal.value = true;
}

// 关闭编辑对话框
const closeEditModal =async () => {
    // const res = await GlobalAPI.update_user_record(currentConversation.value.chatId,editingTitle.value)
    // if (res.ok) {
    //     fetchData()
    //     window.$ModalMessage.success(`编辑成功`)

    // }
  showEditModal.value = false;
}

// 确认编辑
const confirmEdit = () => {
  if (editingTitle.value.trim()) {
    console.log('修改对话标题:', currentConversation.value, '新标题:', editingTitle.value);
    // 这里添加实际的更新标题逻辑
  }
  closeEditModal();
}
const fetchData=()=>{
    return new Promise((resolve)=>{
        let page=1
            let limit=999999
            
            GlobalAPI.query_user_qa_record(page,limit).then(res => {
                if (res.ok) {
                    console.log(res,'res.json()')
                    return res.json();
                }
                throw new Error('获取对话历史失败');
            }).then(data => {
                console.log('data12333', data)
                if (data) {
                    // 更新 tableData
                    tableData.value = data;
                    resolve(data)
                }
            }).catch(err => {
                console.error('更新对话历史失败:', err);
            });
         
    })
       
}

const fetchAPPData=()=>{
    return new Promise((resolve)=>{
        let page=1
            let limit=999999
           
            GlobalAPI.query_user_qa_record(page,limit,appId.value).then(res => {
                if (res.ok) {
                    console.log(res,'res.json()')
                    return res.json();
                }
                throw new Error('获取对话历史失败');
            }).then(data => {
                console.log('data12333', data)
                if (data) {
                  let tableDataList=[]
                    // 更新 tableData
                    tableAppData.value = data;
                    if(tableAppData.value.length>0){
                      data.forEach(item => {
                    console.log(item,'item1233')
                    Object.keys(item).forEach(key => {
                      console.log(item[key],'key123')
                      tableDataList.push(...item[key])
                      // if(key!=='更久之前'){
                      // searchResultsList.push(...item[key])
                      // }
                    });
                })
                console.log(tableDataList,'tableDataList')
                      handleConversationClick(tableDataList[0],false)

                    }
                    resolve(data)
                }
            }).catch(err => {
                console.error('更新对话历史失败:', err);
            });
         
    })
       
}

const fetchResultData=()=>{
    return new Promise((resolve)=>{
        let page=1
            let limit=999999
            let appId=''
            GlobalAPI.query_user_qa_record(page,limit,appId).then(res => {
                if (res.ok) {
                    console.log(res,'res.json()')
                    return res.json();
                }
                throw new Error('获取对话历史失败');
            }).then(data => {
                console.log('data12333', data)
                if (data) {
                    // 更新 tableData
                    // tableData.value = data;
                    let searchResultsList=[]
                data.forEach(item => {
                    console.log(item,'item1233')
                    Object.keys(item).forEach(key => {
                      console.log(item[key],'key123')
                      if(key!=='更久之前'){
                      searchResultsList.push(...item[key])
                      }
                    });
                })
                 console.log(searchResultsList,'searchResultsList')
                    searchResults.value = searchResultsList;
                    resolve(data)
                }
            }).catch(err => {
                console.error('更新对话历史失败:', err);
            });
         
    })
       
}
// const getUserDetail=(id)=>{
//     GlobalAPI.search_user_record_detail(id).then(res => {
//         if (res.ok) {
//             console.log(res,'res.json()')
//             return res.json();
//         }
//         throw new Error('获取用户信息失败');
//     }).then(data => {
//         console.log('data12333', data)
//         if (data ) {
//             // 更新 tableData
//             // userDetail.value = data;
//         }
//     }).catch(err => {
//         console.error('更新用户信息失败:', err);
//     });
// }
// 添加一个响应式变量来存储用户详情数据
const userDetail = ref([]);
function transformData(data) {
  // 创建一个以messageId为键的映射，用于存储有question的项
  const messageMap = {};
  
  // 首先遍历所有项，将有question的项存入映射
  data.forEach(item => {
    if (item.question !== "") {
      messageMap[item.messageId] = item;
    }
  });
  
  // 再次遍历，将无question的项的modelAnswer添加到对应messageId的项的chatAnswer中
  data.forEach(item => {
    if (item.question === "" && messageMap[item.messageId]) {
      messageMap[item.messageId].chartAnswer = JSON.parse(item.modelAnswer);
    }
  });
  
  // 返回映射中的值（即有question的项，现在可能添加了chatAnswer）
  return Object.values(messageMap);
}
// 修改 getUserDetail 函数
const getUserDetail = (id) => {
    GlobalAPI.search_user_record_detail(id).then(res => {
        if (res.ok) {
            console.log(res, 'res.json()')
            return res.json();
        }
        throw new Error('获取用户信息失败');
    }).then(data => {
        console.log('用户详情数据:', data)
        if (data) {
            const originalData = [...data]; // 你的原始数据
            const transformedData = transformData(originalData);
            // 更新用户详情数据
            data= transformedData
            userDetail.value = transformedData;
            // data=data[1]
            console.log('转换后的数据:', transformedData);
            // 清空当前对话内容
            conversationItems.value = [];
            
            // 将用户详情数据转换为对话格式并添加到 conversationItems
            if (Array.isArray(data) && data.length > 0) {
                data.forEach(item => {
                    // 添加用户问题
                    conversationItems.value.push({
                        chat_id: item.id || uuid.value,
                        qa_type: item.qaType || 'COMMON_QA',
                        question: item.question || '',
                        file_key:  '',
                        role: 'user',
                        rating:item.rating,
                        file_name:item.fileKey,
                        file_size:item.fileSize,
                        file_url:item.fileUrl,
                        reader: null
                    });
                    
                    // 添加AI回答
                    let modelAnswer = '';
try {
    // 尝试解析 modelAnswer 字段
    const answerObj = JSON.parse(item.modelAnswer);
    if (answerObj && answerObj.data && answerObj.data.content) {
        modelAnswer = answerObj.data.content;
    } else {
        // 如果解析后的对象结构不符合预期，直接使用原始字符串
        modelAnswer = item.modelAnswer || '';
    }
} catch (e) {
    console.error('解析 modelAnswer 失败:', e);
    // 解析失败时直接使用原始字符串
    modelAnswer = item.modelAnswer || '';
}
                    
                    conversationItems.value.push({
                        chat_id: item.id || uuid.value,
                        qa_type: item.qaType || 'COMMON_QA',
                        question: item.question || '',
                        file_key: item.fileKey || '',
                        role: 'assistant',
                        rating:item.rating,
                        reader: null,
                        answer: modelAnswer,
                        chartAnswer: item.chartAnswer || ''
                    });
                
                    // if(item.chartAnswer){
                    //     const answerObj = JSON.parse(item.chartAnswer);
                    //         if (answerObj && answerObj.dataType === 't04') {
                    //             // 如果是图表数据，更新到 writerList
                    //             businessStore.update_writerList(answerObj);
                    //             console.log('更新 writerList 成功:', answerObj);
        
                    //         }
                    // }else{
                    //     businessStore.update_writerList({});
                    //     console.log('清除新 writerList 成功:', {});

                    // }
                });
                
                // 更新 currentRenderIndex 以显示所有对话
                currentRenderIndex.value = conversationItems.value.length - 1;
                
                // 关闭默认页面
                showDefaultPage.value = false;
            }
        }
    }).catch(err => {
        console.error('更新用户信息失败:', err);
        window.$ModalMessage.error('获取对话详情失败');
    });
}
// const isCurrentChat =  ((chatId) => {
//     return conversationList.chatId === chatId
// })
const isCurrentChat = computed(() => {
  return (chatId) => conversationList.chatId === chatId
})
//文件上传
let file_name = ref('')
const uploadedFiles = ref([]) 

const getFileTypeIcon = (fileType: string) => {
  switch (fileType.toLowerCase()) {
    case 'txt':
      return 'i-vscode-icons:file-type-text'
    case 'md':
    case 'markdown':
      return 'i-vscode-icons:file-type-markdown'
    case 'pdf':
      return 'i-vscode-icons:file-type-pdf'
    case 'html':
      return 'i-vscode-icons:file-type-html'
    case 'xlsx':
    case 'xls':
      return 'i-vscode-icons:file-type-excel2'
    case 'docx':
      return 'i-vscode-icons:file-type-word'
    case 'csv':
      return 'i-vscode-icons:file-type-csv'
    case 'eml':
    case 'msg':
      return 'i-vscode-icons:file-type-email'
    case 'pptx':
    case 'ppt':
      return 'i-vscode-icons:file-type-powerpoint'
    case 'xml':
      return 'i-vscode-icons:file-type-xml'
    case 'epub':
      return 'i-vscode-icons:file-type-epub'
    default:
      return 'i-vscode-icons:file-type-text' // 默认图标
  }
}

const getFileTypeColor = (fileType: string) => {
  switch (fileType.toLowerCase()) {
    case 'txt':
      return '#6C757D' // 灰色
    case 'md':
    case 'markdown':
      return '#2196F3' // 蓝色
    case 'pdf':
      return '#F44336' // 红色
    case 'html':
      return '#FF5722' // 橙色
    case 'xlsx':
    case 'xls':
      return '#4CAF50' // 绿色
    case 'docx':
      return '#2196F3' // 蓝色
    case 'csv':
      return '#9C27B0' // 紫色
    case 'eml':
    case 'msg':
      return '#00BCD4' // 青色
    case 'pptx':
    case 'ppt':
      return '#FF9800' // 橙色
    case 'xml':
      return '#607D8B' // 蓝灰色
    case 'epub':
      return '#795548' // 棕色
    default:
      return '#9E9E9E' // 默认灰色
  }
}
// 获取文件类型
const getFileTypeName = (fileName: string) => {
  const extension = fileName.split('.').pop()?.toLowerCase() || ''
  return extension
}
// 新增：存储已上传文件列表

// const finish_upload = (res) => {
//     file_name.value = res.file.name
//     if (res.event.target.responseText) {
//         let json_data = JSON.parse(res.event.target.responseText)
//         // 修改这里的数据解析逻辑，适应新的返回格式
//         let file_url = ''
        
//         // 检查返回的数据结构并正确提取 file_url
//         if (json_data.object_key) {
//             // 直接使用 object_key
//             file_url = json_data.object_key
//         } else if (json_data.data && json_data.data.object_key) {
//             // 使用嵌套的 data.object_key
//             file_url = json_data.data.object_key
//         } else if (json_data.url) {
//             // 使用 url 字段
//             file_url = json_data.url
//         } else {
//             window.$ModalMessage.error(`文件上传失败：无效的返回格式`)
//             return
//         }
        
//         // 检查是否有成功标志，如果没有则假定成功
//         const isSuccess = json_data.code === 200 || json_data.object_key || json_data.url
        
//         if (isSuccess) {
//             onAqtiveChange('FILEDATA_QA')
//             businessStore.update_file_url(file_url)
            
//             // 添加文件到文件列表
//             uploadedFiles.value.push({
//                 name: file_name.value,
//                 url: file_url,
//                 size: res.file.size,
//                 type: res.file.type
//             })
//             // uploadedFiles=uploadedFiles[uploadedFiles.length-1]
//             window.$ModalMessage.success(`文件上传成功`)
//         } else {
//             window.$ModalMessage.error(`文件上传失败`)
//             return
//         }
//         var query_text = file_name.value + ' 总结归纳文档的关键信息'
//         // handleCreateStylized(query_text)
//     }
// }

// 删除已上传文件

// 添加上传进度相关的响应式变量
const uploadProgress = ref(0)
const isUploading = ref(false)
const uploadStatus = ref('') // 用于显示上传状态信息
const currentUploadId = ref(null)
const file_urlList = ref('')
//额外数据
const upload_data=ref({
    appId:appId.value,
    userId:'1',
})
const uploadFileId=ref('')
const getFileType=(res)=>{
   let data={
    'IMAGE_QA':'image',
    'FILEDATA_QA':'document',
    'AUDIO_QA':'audio',
   }
   return data[res]?data[res]:''
}
const finish_upload = (res) => {
    isUploading.value = false
    // uploadProgress.value = 100
    uploadStatus.value = '上传完成'
    
    file_name.value = res.file.name
    console.log('resfinish_upload', file_name.value)
    if (res.event.target.responseText) {
        let json_data = JSON.parse(res.event.target.responseText)
        uploadFileId.value=json_data.id
        return
        // 修改这里的数据解析逻辑，适应新的返回格式
        let file_url = ''
        
        // 检查返回的数据结构并正确提取 file_url
        if (json_data.object_key) {
            // 直接使用 object_key
            file_url = json_data.object_key
            file_urlList.value = json_data.url
            console.log('file_urlobject_key1', file_urlList.value )
        } else if (json_data.data && json_data.data.object_key) {
            // 使用嵌套的 data.object_key
            file_url = json_data.data.object_key
            console.log('file_urlobject_key2', file_url)

        } else if (json_data.url) {
            // 使用 url 字段
            // file_url = json_data.url
            file_urlList.value=json_data.url
            console.log('file_urlobject_key3', file_url)


        } else {
            window.$ModalMessage.error(`文件上传失败：无效的返回格式`)
            uploadStatus.value = '上传失败'
            return
        }
        
        // 检查是否有成功标志，如果没有则假定成功
        const isSuccess = json_data.code === 200 || json_data.object_key || json_data.url
        
        if (isSuccess) {
            onAqtiveChange('FILEDATA_QA')
            businessStore.update_file_url(file_url)
            
            // // 添加文件到文件列表
            // uploadedFiles.value.push({
            //     name: file_name.value,
            //     url: file_url,
            //     size: res.file.size,
            //     type: res.file.type
            // })
            
            window.$ModalMessage.success(`文件上传成功`)
            uploadStatus.value = '上传成功'
            
            // 3秒后重置上传状态
            setTimeout(() => {
                // uploadProgress.value = 0
                uploadStatus.value = ''
            }, 3000)
        } else {
            window.$ModalMessage.error(`文件上传失败`)
            uploadStatus.value = '上传失败'
            return
        }
        var query_text = file_name.value + ' 总结归纳文档的关键信息'
        // handleCreateStylized(query_text)
    }
}


// 处理文件列表变化
const handleFileListChange = (files) => {
    console.log('文件列表变化:', files)
    if (files.length > 0) {
         
            
        const latestFile = files[files.length - 1]
        if (latestFile.status === 'uploading') {
            isUploading.value = true
            currentUploadId.value = latestFile.id
            
            // 如果文件有进度信息
            if (latestFile.percentage !== undefined) {
                uploadProgress.value = Math.round(latestFile.percentage)
                console.log('上传进度:', uploadProgress.value)
                uploadStatus.value = `上传中 ${uploadProgress.value}%`
            }
        } else if (latestFile.status === 'finished') {
            uploadProgress.value = 100
            uploadStatus.value = '上传完成'
            setTimeout(() => {
                isUploading.value = false
                uploadStatus.value = ''
            }, 2000)
        } else if (latestFile.status === 'error') {
            uploadProgress.value = 0
            uploadStatus.value = '上传失败'
            isUploading.value = false
        }
    }
}
// 添加预览图片的响应式变量
const previewImage = ref('')
const showPreviewModal = ref(false)
const previewImageUrl = ref('')

const handleImagePreview = () => {
  previewImageUrl.value = previewImage.value
  showPreviewModal.value = true
}
// 添加上传错误处理函数
const handleUploadError = (e) => {
    isUploading.value = false
    uploadProgress.value = 0
    uploadStatus.value = '上传失败'
    window.$ModalMessage.error(`文件上传失败: ${e.message || '未知错误'}`)
}

const handleUploadStart = (options) => {
    console.log('上传开始:', options)

    // 判断文件类型
    if (options.file.type.startsWith('image/')) {
        console.log('image开始:')

        onAqtiveChange('IMAGE_QA')
        const reader = new FileReader()
    reader.onload = (e) => {
        console.log('image开始:111', e)
      const base64 = e.target?.result as string
      // 设置预览图片
      previewImage.value = base64
   
      console.log('预览图片:', previewImage.value)
      // 如果需要阻止原有的上传流程，返回false
      // 如果需要继续原有的上传流程，返回true
 
    }
    reader.readAsDataURL(options.file.file)
    // console.log("✅ 这是图片文件:", file.name, "类型:", file.type);
  } else if (options.file.type.startsWith('audio/')) {
    onAqtiveChange('VOICE_QA')
    // console.log("🎵 这是音频文件:", file.name, "类型:", file.type);
  } else {
    onAqtiveChange('FILEDATA_QA')
    // console.log("📄 这是普通文件:", file.name, "类型:", file.type);
        // 添加文件到文件列表
        uploadedFiles.value.push({
        name: options.file.name,
        size: options.file.file.size,
        type: options.file.type
    })
    uploadedFiles.value= [uploadedFiles.value[uploadedFiles.value.length-1]]

  }

    console.log('文件列表:1',uploadedFiles.value[0], uploadedFiles.value.length-1 )
    isUploading.value = true
    uploadProgress.value = 0
    uploadStatus.value = '准备上传...'
    // uploadedFiles.value=uploadedFiles.value[uploadedFiles.value.length-1]
    // 添加进度监听
    const xhr = options.xhr
    if (xhr) {
        xhr.upload.addEventListener('progress', (e) => {
            if (e.lengthComputable) {
                const percent = Math.round((e.loaded / e.total) * 100)
                console.log('原始上传进度:', percent, e.loaded, e.total)
                uploadProgress.value = percent
                uploadStatus.value = `上传中 ${percent}%`
            }
        }, false)
    }
    return true

}
// 修改上传组件配置，使用自定义请求
// const customRequest = ({ file, data, headers, withCredentials, action, onFinish, onError, onProgress }) => {
//     const formData = new FormData()
//     formData.append('file', file.file)
    
//     if (data) {
//         Object.keys(data).forEach(key => {
//             formData.append(key, data[key])
//         })
//     }
    
//     const xhr = new XMLHttpRequest()
//     xhr.open('POST', baseUrl + "/api/file/upload")
    
//     if (headers) {
//         Object.keys(headers).forEach(key => {
//             xhr.setRequestHeader(key, headers[key])
//         })
//     }
    
//     xhr.withCredentials = withCredentials
    
//     // 监听上传进度
//     xhr.upload.addEventListener('progress', e => {
//         if (e.lengthComputable) {
//             const percent = Math.round((e.loaded / e.total) * 100)
//             console.log('自定义请求上传进度:', percent, e.loaded, e.total)
//             uploadProgress.value = percent
//             uploadStatus.value = `上传中 ${percent}%`
//             onProgress({ percent })
//         }
//     })
    
//     xhr.onload = function() {
//         if (xhr.status === 200) {
//             try {
//                 const response = JSON.parse(xhr.responseText)
//                 onFinish({ response, status: 'success' })
//             } catch (e) {
//                 onError(e)
//             }
//         } else {
//             onError(new Error(`上传失败: ${xhr.status}`))
//         }
//     }
    
//     xhr.onerror = function() {
//         onError(new Error('网络错误'))
//     }
    
//     xhr.send(formData)
    
//     return {
//         abort() {
//             xhr.abort()
//         }
//     }
// }
const removeImage = () => {
    previewImage.value = ''
}
const removeFile = (index) => {
    const removedFile = uploadedFiles.value[index]
    uploadedFiles.value.splice(index, 1)
    
    // 如果删除的是当前使用的文件，清空文件URL
    if (removedFile.url === businessStore.$state.file_url) {
        businessStore.update_file_url('')
    }
    
    window.$ModalMessage.success(`文件已删除`)
}
const downloadExecl=(value) => {
    console.log('value', value)
    const link = document.createElement('a')
    link.href = value
    // link.download = '文件名称.xlsx'
    link.click()
    // window.open(value)
}
// 在 setup 函数中添加以下变量和方法
const showAcademicSearch = ref(true)

// 关闭学术搜索面板
const closeAcademicSearch = () => {
    
    hasAppModel.value = false
}

// 加载相关会话
const loadRelatedConversation = (title) => {
    // 这里可以实现加载相关会话的逻辑
    console.log('加载相关会话:', title)
    // 可以根据标题查找对应的会话并加载
    window.$ModalMessage.info(`正在加载会话: ${title}`)
}
</script>
<template>
    <LayoutCenterPanel :loading="loading">
        <div
            class="flex justify-between items-center h-full"
            style="background: linear-gradient(to right, #f3f3f3, #ffffff)"
        >
            <!-- 第一列，宽度为200px -->
          <!-- 修改侧边栏部分 -->
<!-- 修改侧边栏部分，添加可伸展功能 -->
<div
    :class="{'w-[260px]': !sidebarCollapsed, 'w-[60px]': sidebarCollapsed}"
    style="
        height: 98%;
        border-top-left-radius: 20px;
        border-bottom-left-radius: 20px;
        background-color: #f3f3f3 !important;
        display: flex;
        flex-direction: column;
        transition: width 0.3s ease;
        position: relative;
    "
>
    <!-- 添加侧边栏切换按钮 -->
    <!-- <div 
        class="sidebar-toggle"
        @click="toggleSidebar"
        style="
            position: absolute;
            right: -12px;
            top: 50%;
            transform: translateY(-50%);
            width: 24px;
            height: 24px;
            background-color: #fff;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            z-index: 10;
        "
    >
        <n-icon size="16">
            <div :class="sidebarCollapsed ? 'i-hugeicons:chevron-right' : 'i-hugeicons:chevron-left'"></div>
        </n-icon>
    </div> -->

    <n-layout
        class="custom-layout"
        :native-scrollbar="true"
        ref="scrollableContainer"
        @mouseenter="showScrollbar"
        @mouseleave="hideScrollbar"
    >
        <n-layout-header
            class="header"
            style="
                display: flex;
                align-items: center;
                justify-content: space-between;
                flex-shrink: 0;
                position: sticky;
                top: 0;
                z-index: 1;
                background: #f3f3f3;
                padding: 16px 20px;
            "
        >
            <div style="font-size: 18px; font-weight: bold;" v-if="!sidebarCollapsed">AI大模型</div>
            <!-- <div style="font-size: 18px; font-weight: bold;" v-else>元宝</div> -->
            <div style="display: flex; gap: 10px;" >
                <n-tooltip placement="left-start" trigger="hover" v-if="!sidebarCollapsed">
    <template #trigger>
        <n-icon size="20" class="icon"  @click="openSearchModal">
                    <div class="i-hugeicons:search-01"></div>
                </n-icon>
    </template>
    搜索对话
  </n-tooltip>
  <n-tooltip placement="right-start" trigger="hover">
    <template #trigger>
        <n-icon size="20" class="icon" @click="toggleSidebar">
              <svg t="1747036664341" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8456" width="200" height="200"><path d="M924.306286 0H73.142857a73.142857 73.142857 0 0 0 0 146.285714h851.163429a73.142857 73.142857 0 1 0 0-146.285714zM575.268571 438.857143H73.142857a73.142857 73.142857 0 0 0 0 146.285714h501.979429a73.142857 73.142857 0 0 0 0.146285-146.285714z m349.037715 438.857143H73.142857a73.142857 73.142857 0 0 0 0 146.285714h851.163429a73.142857 73.142857 0 1 0 0-146.285714z m54.857143-251.245715V397.677714c0-28.379429-38.473143-42.642286-60.928-22.528l-128 114.395429a29.549714 29.549714 0 0 0 0 45.129143l128 114.395428c22.454857 19.968 60.928 5.778286 60.928-22.601143z" fill="#666666" p-id="8457"></path></svg>
                </n-icon>
    </template>
    收起侧栏
  </n-tooltip>
              
                
            </div>
        </n-layout-header>
        
        <!-- 新建对话按钮 -->
        <div style="padding: 10px 15px;">
            <n-button
                type="primary"
                icon-placement="left"
                color="#ffffff"
                @click="newChat"
                strong  
                class="new-chat-button"
                style="
                    width: 100%;
                    height: 40px;
                    margin-bottom: 16px;
                    text-align: center;
                    font-weight: bold;
                    font-size: 14px;
                    color: #191919;
                    border: 1px solid #ffffff;
                    border-radius: 8px;
                "
            >
                <template #icon>
                    <n-icon >
                        <div class="i-hugeicons:add-01"></div>
                    </n-icon>
                </template>
                <span v-if="!sidebarCollapsed">新建对话</span>
            </n-button>
        </div>
        
        <!-- 我的收藏 -->
        <div style="padding: 0 10px;margin-bottom: 16px;" v-if="!sidebarCollapsed">
            <n-button
                quaternary
                icon-placement="left"
                style="
                    width: 100%;
                    height: 40px;
                    text-align: left;
                    font-size: 14px;
                    display: block;
                "
                @click="toggleAppMarketplace('MyApp')"
            >
             <div style="display: flex;justify-content: space-between;">
                 <div style="display: flex; align-items: center;">
                     <n-icon size="18" style="margin-right: 8px;">
                        <svg t="1747545538394" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12051" width="200" height="200"><path d="M1008.856237 306.55521L790.267652 525.175794a51.487196 51.487196 0 0 1-72.846862 0L498.832206 306.55521a51.423197 51.423197 0 0 1 0-72.830862L717.42079 15.111764a51.463196 51.463196 0 0 1 72.846862 0l218.588585 218.620584a51.375197 51.375197 0 0 1 0 72.822862zM754.252215 68.190935L551.967376 270.539773l202.284839 202.356838 202.276839-202.356838L754.252215 68.190935zM370.434212 1024H57.687099a56.863112 56.863112 0 0 1-56.863112-56.855112v-312.795112a56.831112 56.831112 0 0 1 56.863112-56.831112h312.747113a56.855112 56.855112 0 0 1 56.863111 56.831112v312.795112a56.887111 56.887111 0 0 1-56.863111 56.855112z m-5.223918-364.434306H62.911017v302.339276h302.307276V659.565694z m5.223918-147.357697H57.687099A56.839112 56.839112 0 0 1 0.823987 455.352885V142.605772a56.863112 56.863112 0 0 1 56.863112-56.863112h312.747113a56.879111 56.879111 0 0 1 56.863111 56.863112V455.352885a56.863112 56.863112 0 0 1-56.863111 56.855112z m-5.223918-364.378307H62.911017v302.307277h302.307276V147.82969z m204.252808 449.688974h312.747113a56.855112 56.855112 0 0 1 56.847112 56.831112v312.795112a56.879111 56.879111 0 0 1-56.847112 56.855112H569.463102a56.863112 56.863112 0 0 1-56.871111-56.855112v-312.795112a56.831112 56.831112 0 0 1 56.871111-56.831112z m5.207919 364.386306h302.299276V659.565694H574.671021v302.339276z" p-id="12052" fill="#8a8a8a"></path></svg>                            </n-icon>
                     我的应用
                 </div>
                 <div>
                     <n-icon size="16">
                         <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20"><g fill="none"><path d="M12.22 6.03a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06L16.19 10l-3.97-3.97z" fill="currentColor"></path></g></svg>
                     </n-icon>
                 </div>
             </div>
            </n-button>
            <n-button
                quaternary
                icon-placement="left"
                style="
                    width: 100%;
                    height: 40px;
                    text-align: left;
                    font-size: 14px;
                    display: block;
                "
                @click="toggleAppMarketplace('knowLedge')"
            >
             <div style="display: flex;justify-content: space-between;">
                 <div style="display: flex; align-items: center;">
                     <n-icon size="18" style="margin-right: 8px;">
                        <svg t="1747645112733" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14200" width="200" height="200"><path d="M64 192v640c0 70.7 57.3 128 128 128V64c-70.7 0-128 57.3-128 128zM832 64v255.1L703.8 192 576 320V64H256v896h576c70.7 0 128-57.3 128-128V192c0-70.7-57.3-128-128-128z m0 640H384v-64h448v64z m0-192H384v-64h448v64z" fill="#8a8a8a" p-id="14201"></path></svg>                         </n-icon>
                     知识库 
                 </div>
                 <div>
                     <n-icon size="16">
                        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20"><g fill="none"><path d="M12.22 6.03a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06L16.19 10l-3.97-3.97z" fill="currentColor"></path></g></svg>
                    </n-icon>
                    </div>
             </div>
            </n-button>
        </div>
        <div style="padding: 0 20px; margin-bottom: 16px; text-align: center;" v-else>
            <n-icon size="24">
                <div class="i-hugeicons:bookmark"></div>
            </n-icon>
        </div>
        
        <!-- 分组 -->
<!--        <div style="padding: 0 20px; margin-bottom: 16px;" v-if="!sidebarCollapsed">-->
<!--            &lt;!&ndash; 分组内容保持不变 &ndash;&gt;-->
<!--            <div style="-->
<!--                display: flex;-->
<!--                justify-content: space-between;-->
<!--                align-items: center;-->
<!--                color: #999;-->
<!--                font-size: 14px;-->
<!--                margin-bottom: 10px;-->
<!--            ">-->
<!--                <span>分组</span>-->
<!--                <n-icon size="18">-->
<!--                    <div class="i-hugeicons:add"></div>-->
<!--                </n-icon>-->
<!--            </div>-->
<!--            -->
<!--            &lt;!&ndash; 英文翻译分组 &ndash;&gt;-->
<!--            <n-button-->
<!--                quaternary-->
<!--                icon-placement="left"-->
<!--                style="-->
<!--                    width: 100%;-->
<!--                    height: 40px;-->
<!--                    text-align: left;-->
<!--                    font-size: 14px;-->
<!--                    margin-bottom: 10px;-->
<!--                "-->
<!--            >-->
<!--                <template #icon>-->
<!--                    <n-icon size="18" style="margin-right: 8px;">-->
<!--                        <div class="i-hugeicons:folder"></div>-->
<!--                    </n-icon>-->
<!--                </template>-->
<!--                英文翻译-->
<!--            </n-button>-->
<!--        </div>-->
        <div style="padding: 0 20px; margin-bottom: 16px; text-align: center;" v-else>
            <n-icon size="24">
                <div class="i-hugeicons:folder"></div>
            </n-icon>
        </div>
        
        <!-- 今天和本月的对话历史 - 仅在展开时显示 -->
        <template v-if="!sidebarCollapsed">
    <!-- 遍历对话分组 -->
<div class="tableData">
    <div v-for="(group, groupIndex) in tableData" :key="groupIndex">
      <div v-for="(conversations, groupName) in group" :key="groupName">
        <!-- 只显示有对话的分组 -->
        <div v-if="conversations && Array.isArray(conversations) && conversations.length > 0" style="padding: 0 20px; margin-bottom: 10px;">          <div style="
              color: #999;
              font-size: 14px;
              margin-bottom: 10px;
          ">
            {{ groupName }}
          </div>
          
          <div style="padding: 0 0px; margin-bottom: 10px;" datatype="123">
            <n-data-table
  class="custom-table"
  :bordered="false"
  :single-line="false"
  :columns="[
    {
      key: 'title',
      render: (row) => {
         // 确保 row 是有效对象
         if (!row) return null;
        return h('div', {
          class: 'table-cell-wrapper',
          style: {
            position: 'relative',
            width: '100%',
          },
          dataId:row.chatId
        }, [
          h(NButton, {
            quaternary: true,
            style: {
              width: '100%',
              height: '40px',
              textAlign: 'left',
              fontSize: '14px',
              padding: '0',
              display: 'block',
              alignItems: 'center',
              paddingLeft: '10px',
              backgroundColor: isCurrentChat(row.chatId) ? '#e1e2e2' : '', // 根据是否是当前对话设置背景色
              borderRadius: '8px',
            },
            onClick: () => handleConversationClick(row,true) // 添加点击事件处理函数
          }, { 
            default: () => [
              h('div', {
                style: {
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  gap: '8px'
                }
              },[
                h('span', {
                  style: {
                    maxWidth: '160px', // 设置最大宽度
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    height: '18px',
                    whiteSpace: 'nowrap',
                    display: 'inline-block'
                  }
                }, row.title || '未命名对话'),
                h(NDropdown, {
                  trigger: 'click',
                  options: [
                  
                    {
                      label: '编辑名称',
                      key: 'edit',
                      icon: () => h('div', { class: 'i-hugeicons:edit' })
                    },
                 
                    {
                        label: () => h('span', { style: 'color: #f56c6c;' }, '删除'),
                      key: 'delete',
                      icon: () => h('div', { class: 'i-hugeicons:trash' })
                    }
                  ],
                  onSelect: (key) => handleMoreAction(key, row) // 添加下拉菜单选择事件处理函数
                }, {
                  default: () => h(NButton, {
                    quaternary: true,
                    circle: true,
                    size: 'small',
                    onClick: (e) => {
                      e.stopPropagation();
                    },
                    style: {
                      marginRight: '5px'
                    }
                  }, {
                    default: () => h(NIcon, { size: 16 }, { 
                      default: () => h('div', { class: 'i-hugeicons:more-vertical',style:{'fontSize':'19px',color:'#000'} })
                    })
                  })
                })
              ]),
            ]
          })
        ])
      }
    }
  ]"
  :data="conversations"
>
</n-data-table>
          </div>
        </div>
      </div>
    </div>
</div>
  </template>
    </n-layout>
    
    <!-- 底部 -->

    
    <!-- 用户信息 -->
    <div 
     @click="toggleAppMarketplace('setting')"
        style="
            padding: 16px 20px;
            display: flex;
            align-items: center;
            gap: 10px;
        "
    >
        <n-avatar
            round
            size="small"
            src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
        />
        <div style="font-size: 14px; font-weight: bold;" v-if="!sidebarCollapsed">YOANALI</div>
        <div style="margin-left: auto;" v-if="!sidebarCollapsed">
            <n-tag size="small" round bordered>
                <n-icon size="12">
                    <div class="i-hugeicons:hexagon"></div>
                </n-icon>
            </n-tag>
        </div>
    </div>
</div>

 <setting v-if="showAppMarketplace==='setting'"/>
  <!-- 应用广场组件 -->
  <MyappLications v-if="showAppMarketplace==='MyApp'"  @select-app="selectApp"/>
  <knowledgeList  v-if="showAppMarketplace==='knowLedge'" />
  
            <!-- 内容区域 -->
            <div
               v-if="showAppMarketplace==='chat'"
                class="flex-1"
                h-full
                style="
                    background: #fcfcfc;
                    display: flex;
                    height: 98%;
                    flex-direction: column;
                    margin-right: 5px;
                "
            >
                <div flex="~ justify-between items-center">
                    <NavigationNavBar :showDefaultPage="showDefaultPage" :conversationList="conversationList" :AppName="AppName" @update-title="updateTitle" @delete-conversation="deleteConvsersation"/>
                </div>

                <!--这里循环渲染即可实现多轮对话-->
                <div
                    flex="1 ~ col"
                    min-h-0
                    pb-20
                    class="scrollable-container"
                    ref="messagesContainer"
                    style="background-color: #fcfcfc"
                >
                    <!--默认对话页面-->
                    <transition name="fade">
                        <div v-if="showDefaultPage">
                            <DefaultPage :AppDescription="AppDescription"/>
                        </div>
                    </transition>
                    <div
    v-show="!showDefaultPage && shouldShowScrollButton"
    style="
        position: fixed;
        right: 39%;
        bottom: 24%;
        z-index: 100;
    "
>
    <n-button
        circle
        secondary
        @click="scrollToBottom"
        style="
            background-color: #fff;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
        "
    >
        <template #icon>
            <n-icon size="20">
              <svg t="1749620977349" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2320" width="200" height="200"><path d="M232.096 389.248a32 32 0 0 1 44.96-45.344l2.88 2.848L512 607.84l232.096-261.12a32 32 0 0 1 41.984-5.12l3.2 2.496a32 32 0 0 1 5.12 41.984l-2.496 3.2-256 288a32 32 0 0 1-44.96 2.816l-2.88-2.848-256-288z" fill="#979797" p-id="2321"></path></svg>
            </n-icon>
        </template>
    </n-button>
</div>
<div class="common-line"></div>
                    <div
                        v-if="!showDefaultPage"
                        v-for="(item, index) in visibleConversationItems"
                        :key="index"
                        class="mb-4"
                        :ref="(el) => setMarkdownPreview(index, el)"
                    >
                        <div v-if="item.role == 'user'" 
                                    >
          <div
          style="
                                    margin-left: 10%;
                                    margin-right: 11.5%;
                                    padding: 15px 15px;
                                    border-radius: 5px;
                                    float: right;"   
                                    >
            <div  class="file-card-preview" @click="downloadExecl(item.file_url)" v-if="item.file_name">
        <div class="file-icon">
            <n-icon size="24" :color="getFileTypeColor(getFileTypeName(item.file_name))">
                <div :class="getFileTypeIcon(getFileTypeName(item.file_name))"></div>
            </n-icon>
        </div>
        <div class="file-info">
            <div class="file-name">{{ item.file_name }}</div>
            <div class="file-meta" v-if="uploadProgress!==100">
            
            </div>
            <div class="file-meta">EXCEL | {{ (item.file_size / 1024).toFixed(2) }}KB</div>
        </div>
    
    </div>
    <div style="
    display: flex;
    justify-content: right;
">
    <div class="image-preview-list" v-viewer="viewerOptions" v-if="item.file_url">
    <img :src="item.file_url" alt="预览图" />
  
</div> 
    </div>
    <div
                                whitespace-break-spaces
                                text-right
                                style="
                                  
                          
                                    padding: 15px 0px;
                                    border-radius: 5px;
                                    text-align: center;
                                    float: right;
                                "
                            >
                                <n-space>
                                
                                    <div
                                        size="large"
                                        :bordered="false"
                                     
                                        :style="{
                                            fontSize: '14px',
                                            fontFamily: 'PMingLiU',
                                       
                                            background: '#f3f3f3',
                                            borderRadius: '12px 2px 12px 12px',
                                            padding: '12px 16px',
                                            borderColor: '#e0dfff'
                                        }"
                                      
                                    >
                                        <!-- <template #avatar>
                                            <n-icon size="25" class="icon">
                                                <svg
                                                    t="1736218313498"
                                                    class="icon"
                                                    viewBox="0 0 1024 1024"
                                                    version="1.1"
                                                    xmlns="http://www.w3.org/2000/svg"
                                                    p-id="6605"
                                                    width="200"
                                                    height="200"
                                                >
                                                    <path
                                                        d="M512 512.002m-511.998 0a511.998 511.998 0 1 0 1023.996 0 511.998 511.998 0 1 0-1023.996 0Z"
                                                        fill="#BE3D27"
                                                        p-id="6606"
                                                    ></path>
                                                    <path
                                                        d="M512.002 512.002m-407.00441 0a407.00441 407.00441 0 1 0 814.00882 0 407.00441 407.00441 0 1 0-814.00882 0Z"
                                                        fill="#E65439"
                                                        p-id="6607"
                                                    ></path>
                                                    <path
                                                        d="M561.053808 655.681439v-49.789806l56.769779-59.443768 21.311916-126.887504 10.523959 4.923981 1.355995-7.875969 15.30794-89.155652L621.659572 178.119304l-159.999375-48.66581-47.959813 31.763876-3.375987 2.235992-24.871903-2.983989v-0.002l-20.36792-2.44399-72.093718 108.095577 50.941801 188.065266v-0.004l15.499939 92.269639 56.773778 59.443768v49.789806l-155.875391 79.999687v84.797669c0 63.451752 102.209601 114.885551 228.295108 114.885551s228.295108-51.435799 228.295109-114.885551v-84.797669l-155.867392-80.001687z"
                                                        fill="#BE3D27"
                                                        p-id="6608"
                                                    ></path>
                                                    <path
                                                        d="M584.425717 619.871579h-144.847434l-155.877391 79.999687v84.797669c0 63.451752 102.213601 114.885551 228.299108 114.885551s228.295108-51.435799 228.295108-114.885551v-84.797669l-155.869391-79.999687z"
                                                        fill="#323232"
                                                        p-id="6609"
                                                    ></path>
                                                    <path
                                                        d="M317.644759 699.871266l155.875391-79.999687h-33.941867l-155.877391 79.999687v84.797669c0 22.113914 12.429951 42.765833 33.945867 60.291764v-145.089433z"
                                                        fill="#494A4A"
                                                        p-id="6610"
                                                    ></path>
                                                    <path
                                                        d="M442.79227 626.239554l-22.435912 11.499955L512 823.238784l86.749661-185.999273-20.957918-10.999957z"
                                                        fill="#E8E9EC"
                                                        p-id="6611"
                                                    ></path>
                                                    <path
                                                        d="M584.425717 637.871508L512 688.305311l-72.421717-50.667802v-149.331416h144.847434z"
                                                        fill="#DE8729"
                                                        p-id="6612"
                                                    ></path>
                                                    <path
                                                        d="M561.031808 488.306093v165.855352l23.393909-16.289937v-149.565415z"
                                                        fill="#F79D22"
                                                        p-id="6613"
                                                    ></path>
                                                    <path
                                                        d="M677.359354 295.328846h-0.479998c0.285999-3.965985 0.479998-7.957969 0.479998-11.999953 0-91.325643-74.035711-165.359354-165.359354-165.359354s-165.359354 74.033711-165.359354 165.359354c0 4.041984 0.195999 8.033969 0.479998 11.999953h-0.479998l0.945996 5.629978c0.695997 6.537974 1.799993 12.947949 3.233988 19.233925l31.983875 190.445256 92.421639 96.769622H548.777856l92.417639-96.769622 31.987875-190.445256a163.78736 163.78736 0 0 0 3.229988-19.233925l0.945996-5.629978z"
                                                        fill="#F79D22"
                                                        p-id="6614"
                                                    ></path>
                                                    <path
                                                        d="M517.323979 333.796696l143.139441 62.111757 3.887985-23.139909-6.523975-40.99184-77.241698-142.471443h-119.367534l-33.685868 24.203905 6.167976 42.797833 25.865899-11.441956 24.203905 11.141957zM406.91441 295.328846H346.640646l36.163859 215.309159 92.421639 96.769622h13.401947l-58.72977-96.769622z"
                                                        fill="#DE8729"
                                                        p-id="6615"
                                                    ></path>
                                                    <path
                                                        d="M598.891661 377.558525m-1.637994 0a1.637994 1.637994 0 1 0 3.275987 0 1.637994 1.637994 0 1 0-3.275987 0Z"
                                                        fill="#DE8729"
                                                        p-id="6616"
                                                    ></path>
                                                    <path
                                                        d="M499.20005 467.052176l9.999961-12.159953v-110.591568l-10.571959-32.141874h-9.999961l10.571959 32.475873zM531.699923 454.892223H509.200011l-9.999961 12.159953h42.499834z"
                                                        fill="#DE8729"
                                                        p-id="6617"
                                                    ></path>
                                                    <path
                                                        d="M437.69829 386.724489m-59.451768 0a59.451768 59.451768 0 1 0 118.903536 0 59.451768 59.451768 0 1 0-118.903536 0Z"
                                                        fill="#494A4A"
                                                        p-id="6618"
                                                    ></path>
                                                    <path
                                                        d="M437.69629 322.272741c-35.539861 0-64.449748 28.913887-64.449748 64.453748s28.909887 64.453748 64.449748 64.453749 64.453748-28.913887 64.453748-64.453749-28.915887-64.453748-64.453748-64.453748z m0 118.905536c-30.027883 0-54.449787-24.427905-54.449787-54.453788s24.421905-54.453787 54.449787-54.453787 54.453787 24.427905 54.453788 54.453787-24.427905 54.453787-54.453788 54.453788z"
                                                        fill="#323232"
                                                        p-id="6619"
                                                    ></path>
                                                    <path
                                                        d="M590.201695 386.724489m-59.451768 0a59.451768 59.451768 0 1 0 118.903535 0 59.451768 59.451768 0 1 0-118.903535 0Z"
                                                        fill="#494A4A"
                                                        p-id="6620"
                                                    ></path>
                                                    <path
                                                        d="M546.479865 346.448647l102.991598 44.691825c0.106-1.459994 0.179999-2.927989 0.179999-4.413983 0-32.835872-26.621896-59.453768-59.453767-59.453767-17.291932 0-32.853872 7.389971-43.71783 19.175925z"
                                                        fill="#323232"
                                                        p-id="6621"
                                                    ></path>
                                                    <path
                                                        d="M590.199695 322.272741c-35.539861 0-64.449748 28.913887-64.449749 64.453748S554.659833 451.178238 590.199695 451.178238s64.453748-28.913887 64.453748-64.453749-28.915887-64.451748-64.453748-64.451748z m0 118.905536c-30.023883 0-54.449787-24.427905-54.449788-54.453788s24.425905-54.453787 54.449788-54.453787c30.027883 0 54.453787 24.427905 54.453787 54.453787S620.225577 441.178277 590.199695 441.178277z"
                                                        fill="#323232"
                                                        p-id="6622"
                                                    ></path>
                                                    <path
                                                        d="M654.323444 393.242464c0.213999-2.141992 0.327999-4.317983 0.327999-6.517975 0-35.539861-28.913887-64.453748-64.453748-64.453748-19.331924 0-36.691857 8.569967-48.515811 22.093914l9.707962 4.211983c9.885961-10.055961 23.627908-16.305936 38.807849-16.305936 30.027883 0 54.453787 24.427905 54.453787 54.453787 0 0.769997-0.028 1.533994-0.062 2.295991l9.733962 4.221984z"
                                                        fill="#323232"
                                                        p-id="6623"
                                                    ></path>
                                                    <path
                                                        d="M437.69629 386.724489m-10.377959 0a10.377959 10.377959 0 1 0 20.755919 0 10.377959 10.377959 0 1 0-20.755919 0Z"
                                                        fill="#323232"
                                                        p-id="6624"
                                                    ></path>
                                                    <path
                                                        d="M590.199695 386.724489m-10.37796 0a10.377959 10.377959 0 1 0 20.755919 0 10.377959 10.377959 0 1 0-20.755919 0Z"
                                                        fill="#323232"
                                                        p-id="6625"
                                                    ></path>
                                                    <path
                                                        d="M528.099937 383.438502c-15.167941-9.483963-28.393889-0.265999-28.523888-0.171999l-5.815978-8.133968c0.761997-0.541998 18.865926-13.165949 39.639845-0.172l-5.299979 8.477967zM362.594584 372.558545h16.355936v9.999961h-16.355936zM649.651462 372.558545h16.351936v9.999961h-16.351936z"
                                                        fill="#323232"
                                                        p-id="6626"
                                                    ></path>
                                                    <path
                                                        d="M406.91441 295.328846l-2.217991-36.355858 12.93795-10.999957 16.065937 8.333968v-15.33394s-26.003898-16.335936-27.003895-15.667939-36.847856 20.667919-35.921859 22.333913c0.921996 1.665993 2.47199 37.665853 2.47199 37.665853l23.449908 22.667911 10.21796-12.643951zM427.53233 311.118785l71.057722 11.017957v-9.977961l-71.057722-11.019957z"
                                                        fill="#DE8729"
                                                        p-id="6627"
                                                    ></path>
                                                    <path
                                                        d="M427.53233 311.118785l71.057722 11.017957v-9.977961l-71.057722-11.019957z"
                                                        fill="#DE8729"
                                                        p-id="6628"
                                                    ></path>
                                                    <path
                                                        d="M364.476576 333.796696l67.831735-23.861907-4.713981-8.795965-67.835735 23.865906z"
                                                        fill="#DE8729"
                                                        p-id="6629"
                                                    ></path>
                                                    <path
                                                        d="M427.59433 301.138824l-9.961961-60.831763-21.599916 3.831985-5.499979 67.499737 15.999938 0.519998z"
                                                        fill="#DE8729"
                                                        p-id="6630"
                                                    ></path>
                                                    <path
                                                        d="M433.700306 256.306999l23.999906-20.665919 35.565861 8.719965 35.483862 76.8017 144.281436 67.511737 16.667935-97.033621-44.667826-149.333417-159.999375-48.66581-51.331799 33.999867-45.241823-5.429978-72.093719 108.095577 50.943801 188.067266 5.723978-64.06775 20.33192-29.033887-1.039996-69.265729 25.307902-15.699939z"
                                                        fill="#323232"
                                                        p-id="6631"
                                                    ></path>
                                                    <path
                                                        d="M417.632369 240.307061l-39.385847 14.495944v70.933723l-18.487927 28.375889 7.54997 64.261749 5.723978-64.06775 20.33192-29.033887-1.039996-69.265729zM645.03148 142.307444l-159.999375-48.66581 136.303468 48.66581 44.667825 149.333417-14.905941 86.771661 21.933914 10.26196 16.667935-97.033621z"
                                                        fill="#494A4A"
                                                        p-id="6632"
                                                    ></path>
                                                    <path
                                                        d="M520.453967 496.138062h-67.235737l9.839961 16.499936 57.395776 24.999902 57.389776-24.999902 9.843961-16.499936z"
                                                        fill="#BE3D27"
                                                        p-id="6633"
                                                    ></path>
                                                    <path
                                                        d="M453.21823 496.138062l8.585966 14.395944h117.293542l8.589966-14.395944h-67.233737z"
                                                        fill="#E8E9EC"
                                                        p-id="6634"
                                                    ></path>
                                                    <path
                                                        d="M829.294761 229.391104c-70.897723 0-128.371499 57.471776-128.371499 128.367499 0 41.327839 19.553924 78.069695 49.889805 101.547603l-81.519681 44.029828 106.581583-28.859887a127.839501 127.839501 0 0 0 53.417792 11.647954c70.893723 0 128.363499-57.471776 128.363498-128.367498s-57.465776-128.365499-128.361498-128.365499z"
                                                        fill="#3AB49C"
                                                        p-id="6635"
                                                    ></path>
                                                    <path
                                                        d="M662.183413 384.456498l-23.889906 66.71974-31.909876 32.909871-1.827993 6.993973-13.257948-24.029906h-143.22144l-17.261933 24.245905-0.831997-2.991988-45.187823-27.333894-17.483932-42.599833v103.367596l64.999746 85.667665 81.397682 25.6659 92.085641-25.6659 56.831778-87.667657v-135.333472l-0.441999 0.052zM546.479865 585.739712h-15.729938l-12.95795-17.499932-12.499951 17.499932h-20.261921l-34.737864-24.499904-16.393936-58.85977 17.061933-11.983954h136.725466l13.541947 13.389948-15.937937 60.953762-38.809849 20.999918z"
                                                        fill="#323232"
                                                        p-id="6636"
                                                    ></path>
                                                    <path
                                                        d="M420.356358 506.208023l1.939992 4.325983 28.663888-20.137922h-8.091968zM591.29569 467.052176H583.199722l22.95591 41.607837 5.13998 5.07998 2.999988-4.99998z"
                                                        fill="#494A4A"
                                                        p-id="6637"
                                                    ></path>
                                                    <path
                                                        d="M662.183413 384.456498l-15.933937 44.499826v90.783646l-56.831778 87.667657-83.393675 23.24191 7.68397 2.42399 92.083641-25.6659 56.833778-87.667657v-135.333472zM368.418561 460.972199l45.187823 27.333894 20.311921 72.933715 34.733864 24.499904h16.379936l-34.739864-24.499904-20.311921-72.933715-45.187823-27.333894-17.483932-42.597833v39.895844z"
                                                        fill="#494A4A"
                                                        p-id="6638"
                                                    ></path>
                                                    <path
                                                        d="M488.86009 711.437221l23.12991-23.13191 23.13191 23.13191-23.13191 23.13191zM499.590048 798.118882l12.409952 25.119902 12.117953-25.981898L512 734.571131z"
                                                        fill="#2A81C2"
                                                        p-id="6639"
                                                    ></path>
                                                    <path
                                                        d="M848.806684 336.652685c-20.049922-7.543971-28.303889-12.497951-28.303889-20.279921 0-6.601974 4.953981-13.201948 20.285921-13.201948 16.975934 0 27.819891 5.417979 33.949867 8.013968l6.843973-26.645895c-7.78197-3.771985-18.397928-7.073972-34.191866-7.77997v-20.751919h-23.10991v22.399912c-25.233901 4.951981-39.851844 21.223917-39.851844 41.973837 0 22.875911 17.213933 34.663865 42.437834 43.151831 17.457932 5.895977 24.999902 11.553955 24.999902 20.51392 0 9.431963-9.191964 14.623943-22.639911 14.623943-15.31994 0-29.237886-4.951981-39.139847-10.37596l-7.073973 27.585892c8.959965 5.18998 24.289905 9.431963 40.085844 10.141961v22.397912h23.113909v-24.051906c27.113894-4.711982 41.975836-22.635912 41.975837-43.621829-0.002-21.219917-11.321956-34.191866-39.381847-44.093828z"
                                                        fill="#EDC848"
                                                        p-id="6640"
                                                    ></path>
                                                </svg>
                                            </n-icon>
                                        </template> -->
                                        {{ item.question }}
                                    </div>
                                </n-space>
                            </div>
          </div>
                         
                            <div
                                v-if="contentLoadingStates[index]"
                                class="i-svg-spinners:bars-scale"
                                style="
                                    width: 24px;
                                    height: 24px;
                                    color: #cccccc;
                                    border-left-color: #cccccc;
                                    margin-top: 155px;
                                    animation: spin 1s linear infinite;
                                    margin-left: 12%;
                                    float: left;
                                "
                            />
                        </div>
                        <div v-if="item.role == 'assistant'">
                            <div v-if="item.answer">
                                <MarkdownPreview
        v-if="item.answer"
        :content="item.answer"
        :chartAnswer="item.chartAnswer"
        :model="defaultLLMTypeName"
        :isInit="false"
        :qaType="`${item.qa_type}`"
        :chart-id="`${index}devID${generateRandomSuffix()}`"
        :rating="item.rating"
        :parentScollBottomMethod="scrollToBottom"
        @failed="() => onFailedReader(index)"
        @completed="() => onCompletedReader(index)"
        @chartready="() => onChartReady(index + 1)"
        @recycleQa="() => onRecycleQa(index)"
        @praiseFeadBack="() => onPraiseFeadBack(index)"
        @belittleFeedback="() => onBelittleFeedback(index)"
        @beginRead="() => onBeginRead(index)"
    />               </div>
                            <MarkdownPreview
                                v-else
                                :reader="item.reader"
                                :model="defaultLLMTypeName"
                                :isInit="isInit"
                                :qaType="`${item.qa_type}`"
                                :chart-id="`${index}devID${generateRandomSuffix()}`"
                                :parentScollBottomMethod="scrollToBottom"
                                :rating="item.rating"
                                @failed="() => onFailedReader(index)"
                                @completed="() => onCompletedReader(index)"
                                @chartready="() => onChartReady(index + 1)"
                                @recycleQa="() => onRecycleQa(index)"
                                @praiseFeadBack="() => onPraiseFeadBack(index)"
                                @belittleFeedback="
                                    () => onBelittleFeedback(index)
                                "
                                @beginRead="() => onBeginRead(index)"
                            />
                        </div>
                    </div>

                    <div
                        v-if="!isInit && !stylizingLoading"
                        style="
                            align-items: center;
                            width: 70%;
                            margin-left: 11%;
                            margin-top: -20px;
                            background-color: #f6f7fb;
                        "
                    >
                        <SuggestedView
                            :labels="suggested_array"
                            @suggested="onSuggested"
                        />
                    </div>
                </div>
          
                <div
                                style="
                                    transform: translateY(-50%);
                                    position: absolute;
                                    margin-left: 11%;
                                    bottom:3%;
                                    z-index:999;
                                "
                            >
                              
                                <!-- 隐藏的文件上传按钮 -->
                                <n-upload
                                    ref="uploadRef"
                                    type="button"
                                    :show-file-list="false"
                                    :action='baseUrl + "/api/file/upload"'
                                    accept=".txt, .md, .markdown, .pdf, .html, .xlsx, .xls, .docx, .csv, .eml, .msg, .pptx, .ppt, .xml, .epub"
                                    style="display: none"
                                    :data="upload_data"
                                    @finish="finish_upload"
                                   :on-update:file-list="handleFileListChange"
                                    @before-upload="handleUploadStart"
                                    @error="handleUploadError"
                                >
                                    选择文件
                                </n-upload>
                                     <!-- 隐藏的图片上传按钮 -->
                                     <n-upload
                                    ref="uploadImgRef"
                                    type="button"
                                    :show-file-list="false"
                                    :action='baseUrl + "/api/file/upload"'
                                    accept=".jpg,.jpeg,.png,.gif,.bmp,.webp,.svg,.tiff,.ico"
                                    style="display: none"
                                    :data="upload_data"
                                    @finish="finish_upload"
                                   :on-update:file-list="handleFileListChange"
                                    @before-upload="handleUploadStart"
                                    @error="handleUploadError"
                                >
                                    选择图片
                                </n-upload>

                  </div>
                
                <div
                    style="
                        align-items: center;
                        background-color: #fcfcfc;
                        margin-right: 5px;
                        border-bottom-right-radius: 10px;
                        flex-shrink: 0;
                    "
                >
                    <div
                        style="
                            position: relative;
                            flex: 1;
                            width: 74%;
                            padding:1em;
                            padding-bottom:0em;
                            padding-top:0em;
                            margin-left: 12.5%;
                            border: 1px solid #dadada;
                            background:#ffffff;
                            border-radius:15px;
                            margin-bottom: 20px;
                        "
                    >
                        <n-space vertical>
                            <div
                                style="
                                    display: flex;
                                    gap: 10px;
                                    margin-left: 0%;        
                                "
                            >                  
<div>
<div >
    <div class="image-preview" v-viewer="viewerOptions" v-if="previewImage">
    <img :src="previewImage" alt="预览图" />
    <div class="file-close-img" @click.stop="removeImage">
        <n-icon size="12">
            <div class="i-carbon:close"></div>
        </n-icon>
    </div>
</div> 
<n-modal v-model:show="showPreviewModal" preset="card" style="width: auto; max-width: 90vw;">
  <img :src="previewImageUrl" style="max-width: 100%; max-height: 80vh; object-fit: contain;" />
</n-modal>
    <div  v-if="uploadedFiles.length>0" class="file-card-container" style=" width: 80%;" >
    <div v-for="(file, index) in uploadedFiles" :key="index" class="file-card" >
        <div class="file-icon">
            <n-icon size="24" :color="getFileTypeColor(getFileTypeName(file.name))">
                <div :class="getFileTypeIcon(getFileTypeName(file.name))"></div>
            </n-icon>
        </div>
        <div class="file-info">
            <div class="file-name">{{ file.name }}</div>
            <div class="file-meta" v-if="uploadProgress!==100">
              上传中...{{ uploadProgress }}%
            </div>
            <div v-else class="file-meta">{{ getFileTypeName(file.name) }} | {{ (file.size / 1024).toFixed(2) }}KB</div>
        </div>
        <div class="file-close" @click="removeFile(index)">
            <n-icon size="16">
                <div class="i-carbon:close"></div>
            </n-icon>
        </div>
    </div>
      <!-- 添加预览区域 -->

</div>
         </div> 
</div>
                            </div>
                            <n-input
                                ref="refInputTextString"
                                v-model:value="inputTextString"
                                type="textarea"
                                autofocus
                                h-60
                                class="textarea-resize-none text-15"
                                :style="{
                                    '--n-border-radius': '0px',
                                    '--n-padding-left': '0px',
                                    '--n-padding-right': '20px',
                                    '--n-padding-vertical': '18px',
                                    '--n-border': 'none',
                                    '--n-border-hover': 'none',
                                    '--n-border-focus': 'none',
                                    '--n-box-shadow-focus': 'none',
                                    width: '100%',
                                    marginLeft: '0%',
                                    align: 'center',
                                  
                                }"
                                :placeholder="placeholder"
                                :autosize="{
                                    minRows: 1,
                                    maxRows: 5
                                }"
                            />
                
                      <div style="display: flex;justify-content:end;align-items: center;padding-right: 45px;height: 42px;">
                      <div style="margin-bottom: 12px;"> 
                        <n-dropdown
                                    :options="options"
                                    @select="handleSelect"
                                >
                                    <n-icon size="30">
                                        <svg
                                            t="1729566080604"
                                            class="icon"
                                            viewBox="0 0 1024 1024"
                                            version="1.1"
                                            xmlns="http://www.w3.org/2000/svg"
                                            p-id="38910"
                                            width="64"
                                            height="64"
                                        >
                                            <path
                                                d="M856.448 606.72v191.744a31.552 31.552 0 0 1-31.488 31.488H194.624a31.552 31.552 0 0 1-31.488-31.488V606.72a31.488 31.488 0 1 1 62.976 0v160.256h567.36V606.72a31.488 31.488 0 1 1 62.976 0zM359.872 381.248c-8.192 0-10.56-5.184-5.376-11.392L500.48 193.152a11.776 11.776 0 0 1 18.752 0l145.856 176.704c5.184 6.272 2.752 11.392-5.376 11.392H359.872z"
                                                fill="#838384"
                                                p-id="38911"
                                            ></path>
                                            <path
                                                d="M540.288 637.248a30.464 30.464 0 1 1-61.056 0V342.656a30.464 30.464 0 1 1 61.056 0v294.592z"
                                                fill="#838384"
                                                p-id="38912"
                                            ></path>
                                        </svg>
                                    </n-icon>
                                </n-dropdown>
                      </div>
                        <!-- 添加语音转文字按钮 -->
                        <div style="margin-left: 14px; margin-bottom: 20px;">
  <n-button
    circle
    :type="isRecording ? 'primary' : 'default'"
    @click="toggleRecording"
    style="margin-right: 10px;"
  >
    <template #icon>
      <n-icon>
        <div :class="isRecording ? 'i-carbon:microphone' : 'i-carbon:microphone'" />
       
      </n-icon>
    </template>
  </n-button>
</div>
                             <div style="margin-left: 14px; margin-bottom: 20px;">
                                <n-float-button
                           
                           :type="stylizingLoading ? 'primary' : 'default'"
                           color
                           :class="[
                               stylizingLoading && 'opacity-90',
                               'text-20'
                           ]"
                           style="transform: translateY(-50%);"
                           @click.stop="handleCreateStylized()"
                       >
                           <div
                               v-if="stylizingLoading"
                               class="i-svg-spinners:pulse-2 c-#fff"
                           ></div>
                           <div
                               v-else
                               class="flex items-center justify-center c-#303133/60 i-mingcute:send-fill"
                           ></div>
                       </n-float-button>
                             </div>
                      </div>
                        </n-space>
                    </div>
                </div>
            </div>
            <!-- <p>识别结果：{{ transcript }}</p> -->
            <div style="height:inherit" >

  <div class="container" @click="hasAppModel=true" v-if="!hasAppModel&&showAppMarketplace==='chat'&&!isCommQa">
<div>
  <div class="dot"></div>
  <div class="dot"></div>
</div>
<div>

  <div class="dot"></div>
  <div class="dot"></div>
</div>
</div>

            </div>
          <!-- 在适当位置添加学术搜索组件 -->
<div
    v-if="hasAppModel&&showAppMarketplace==='chat'"
    class="academic-search-panel"
    style="
     
        right: 20px;
        top: 0;
        width: 300px;
        background-color: #ffff;
        border-radius: 12px;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
        padding: 20px;
        z-index: 100;
        height: 100%;
    "
>
    <div style="position: absolute; top: 10px; right: 10px; cursor: pointer;" @click="closeAcademicSearch">
        <n-icon size="20">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41z"/></svg>
        </n-icon>
    </div>
    
    <div style="display: flex; flex-direction: column; align-items: center; margin-bottom: 20px;">
        <div :style="{backgroundColor:AppIconBackground||'#ffeb3b', width: '80px',height: '80px', borderRadius: '50%','display': 'flex', justifyContent: 'center',alignItems: 'center', marginBottom: '15px'}">
            <!-- <n-icon size="40">
                <svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5l-1.5 1.5l-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16A6.5 6.5 0 0 1 3 9.5A6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14S14 12 14 9.5S12 5 9.5 5z"/></svg>
            </n-icon> -->
            <template v-if="AppIconType === 'emoji'">
            <span class="emoji-icon">{{ AppIcon }}</span>
          </template>
          <template v-else>
            <img :src="AppIcon"  />
          </template>
        </div>
        <h2 style="font-size: 18px; font-weight: bold; margin: 0;">{{ AppName }}</h2>
        <p style="color: #666; font-size: 14px; margin-top: 8px; text-align: center;">{{ AppDescription }}</p>
        <div style="color: #999; font-size: 12px; margin-top: 5px;"> </div>
    </div>
    
    <!-- <div style="display: flex; justify-content: center; gap: 10px; margin-bottom: 20px;">
        <n-button size="small" type="primary" style="background-color: #4a90e2; border: none;">
            <n-icon size="16" style="margin-right: 4px;">
                <svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83l3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
            </n-icon>
            编辑
        </n-button>
        <n-button size="small" style="background-color: #f5f5f5; border: none;">
            <n-icon size="16" style="margin-right: 4px;">
                <svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81c1.66 0 3-1.34 3-3s-1.34-3-3-3s-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65c0 1.61 1.31 2.92 2.92 2.92s2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></svg>
            </n-icon>
            分享
        </n-button>
    </div>  -->
    
    <div style="border-top: 1px solid #eee; padding-top: 15px;height:420px;overflow:auto;margin-bottom:10px">
        <div style="display: flex; align-items: center; margin-bottom: 10px;">
            <n-icon size="18" style="margin-right: 8px; color: #666;">
                <svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10s10-4.5 10-10S17.5 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8zm.5-13H11v6l5.2 3.2l.8-1.3l-4.5-2.7V7z"/></svg>
            </n-icon>
            相关会话
        </div>
          <!-- 遍历对话分组 -->
  <div >
    <div v-for="(group, groupIndex) in tableAppData" :key="groupIndex">
      <div v-for="(conversations, groupName) in group" :key="groupName">
        <!-- 只显示有对话的分组 -->
        <div v-if="conversations && Array.isArray(conversations) && conversations.length > 0" style="padding: 0 20px; margin-bottom: 10px;">          <div style="
              color: #999;
              font-size: 14px;
              margin-bottom: 10px;
          ">
            {{ groupName }}
          </div>
          
          <div style="padding: 0 0px; margin-bottom: 10px;" datatype="123">
            <n-data-table
  class="custom-table"
  :bordered="false"
  :single-line="false"
  :columns="[
    {
      key: 'title',
      render: (row,index) => {
         // 确保 row 是有效对象
         if (!row) return null;
        return h('div', {
          class: 'table-cell-wrapper',
          style: {
            position: 'relative',
            width: '100%',
          },
          dataId:row.chatId
        }, [
          h(NButton, {
            quaternary: true,
            style: {
              width: '100%',
              height: '40px',
              textAlign: 'left',
              fontSize: '14px',
              padding: '0',
              display: 'block',
              alignItems: 'center',
              paddingLeft: '10px',
              backgroundColor: isCurrentChat(row.chatId) ? '' : '', // 根据是否是当前对话设置背景色
              borderRadius: '8px',
            },
            onClick: () => handleConversationClick(row,false) // 添加点击事件处理函数
          }, { 
            default: () => [
              h('div', {
                style: {
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  gap: '8px'
                }
              },[
                h('span', {
                  style: {
                    maxWidth: '160px', // 设置最大宽度
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    height: '18px',
                    whiteSpace: 'nowrap',
                    display: 'inline-block'
                  }
                }, row.title || '未命名对话'),
                h(NDropdown, {
                  trigger: 'click',
                  options: [
                  
                    {
                      label: '编辑名称',
                      key: 'edit',
                      icon: () => h('div', { class: 'i-hugeicons:edit' })
                    },
                 
                    {
                        label: () => h('span', { style: 'color: #f56c6c;' }, '删除'),
                      key: 'delete',
                      icon: () => h('div', { class: 'i-hugeicons:trash' })
                    }
                  ],
                  onSelect: (key) => handleMoreAction(key, row) // 添加下拉菜单选择事件处理函数
                }, {
                  default: () => h(NButton, {
                    quaternary: true,
                    circle: true,
                    size: 'small',
                    onClick: (e) => {
                      e.stopPropagation();
                    },
                    style: {
                      marginRight: '5px'
                    }
                  }, {
                    default: () => h(NIcon, { size: 16 }, { 
                      default: () => h('div', { class: 'i-hugeicons:more-vertical',style:{'fontSize':'19px',color:'#000'} })
                    })
                  })
                })
              ]),
            ]
          })
        ])
      }
    }
  ]"
  :data="conversations"
>
</n-data-table>
          </div>
        </div>
      </div>
    </div>
  </div>
      
    </div>
</div>
        </div>
 
    </LayoutCenterPanel>
    <!-- 在 template 的最后添加搜索弹框 -->

<n-modal
  v-model:show="showSearchModal"

  title="搜索对话"
  style="width: 500px; max-width: 90vw;"
  :mask-closable="true"
  @close="closeSearchModal"
  @after-leave="closeSearchModalL"
>
<n-card
    
      :bordered="false"
      size="huge"
      role="dialog"
      aria-modal="true"
      style="width: 600px; position: fixed; right: 30%; top: 20%"
    >
    <n-input
    
      v-model:value="searchKeyword"
      placeholder="请输入关键词搜索对话"
      clearable
      @update:value="handleInputUpdate"
      @clear="performClear"
    >
      <template #suffix>
        <n-button quaternary circle @click="performSearch">
          <n-icon>
            <div class="i-hugeicons:search-01"></div>
          </n-icon>
        </n-button>
      </template>
    </n-input>
    
    <div v-if="searchResults.length > 0" style="height:300px;overflow-y:auto">
      <n-list hoverable clickable >
        <n-list-item v-for="item in searchResults" :key="item.index" @click="handleSearchResultClick(item)">
          <n-thing>
            <template #header>
              <div class="search-result-item">
                {{ item.title }}
              </div>
            </template>
          </n-thing>
        </n-list-item>
      </n-list>
    </div>
    
    <div v-else-if="searchKeyword && searchResults.length === 0" style="text-align: center; padding: 20px;">
      <n-empty description="未找到相关对话" />
    </div>
  </n-card>
</n-modal>
<!-- 在 template 标签内的末尾添加，</template> 之前 -->

<!-- 编辑对话名称弹框 -->
<n-modal
  v-model:show="showEditModal"
  preset="card"
  title="编辑对话名称"
  style="width: 400px; border-radius: 12px;"
  :mask-closable="false"
  :close-on-esc="true"
>
  <div style="padding: 10px 0;">
    <n-input
      v-model:value="editingTitle"
      type="text"
      placeholder="请输入对话名称"
      autofocus
      style="border-radius: 8px;"
      @keyup.enter="confirmEdit"
    />
  </div>
  <div style="display: flex; justify-content: flex-end; gap: 12px; margin-top: 20px;">
    <n-button
      quaternary
      size="medium"
      style="border-radius: 8px; padding: 0 20px;"
      @click="closeEditModal"
    >
      取消
    </n-button>
    <n-button
      quaternary
      style="border-radius: 8px; padding: 0 20px;"
      @click="confirmEdit"
    >
      确认
    </n-button>
  </div>
</n-modal>
<!-- 删除确认弹框 -->
<n-modal
  v-model:show="showDeleteModal"
  preset="card"
  style="width: 400px; border-radius: 12px;"
  :mask-closable="false"
  :close-on-esc="true"
>
  <div style="display: flex; align-items: center; gap: 12px;">
    <n-icon size="24" color="#f56c6c">
      <div class="i-hugeicons:alert-circle"></div>
    </n-icon>
    <span style="font-size: 18px; font-weight: bold;">确认删除</span>
  </div>
  
  <div style="margin-top: 20px; margin-bottom: 20px; color: #606266;">
    该对话内容将被删除无法恢复。
  </div>
  
  <div style="display: flex; justify-content: flex-end; gap: 12px;">
    <n-button
      quaternary
      size="medium"
      style="border-radius: 8px; padding: 0 20px;"
      @click="closeDeleteModal"
    >
      取消
    </n-button>
    <n-button
      type="error"
      size="medium"
      style="border-radius: 8px; padding: 0 20px;"
      @click="confirmDelete"
    >
      删除
    </n-button>
  </div>
</n-modal>

</template>
<style scoped>


/* 在已有的 style 标签中添加这些样式 */
.sidebar-toggle {
    transition: transform 0.3s ease;
}

.sidebar-toggle:hover {
    transform: translateY(-50%) scale(1.1);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}

/* 确保内容区域也有平滑过渡 */
.flex-1 {
    transition: margin-left 0.3s ease;
}
</style>
<style lang="scss" scoped>
/* 搜索图标样式 */
// .icon {
//   cursor: pointer;
//   transition: transform 0.2s ease;
  
//   &:hover {
//     transform: scale(1.1);
//     color: #8874f1;
//   }
// }
/* 新建对话按钮鼠标移入样式 */
:deep(.new-chat-button:hover) {
  border-color: #e0e0e0 !important;
  transition: all 0.3s ease;
}
/* 搜索结果项样式 */
.search-result-item {
    font-size: 14px;
    font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

:deep(.n-modal-body) {
  max-height: 70vh;
  overflow-y: auto;
}
:deep(.n-input:hover) {
  background-color: #f7f7f7 !important;
}
// :deep(.n-input:focus) {
//   background-color: #f7f7f7 !important;
// }
:deep(.n-input) {
  --n-border-hover: #f7f7f7 !important;
  --n-border-focus: #ffffff !important;
  --n-box-shadow-focus:0 0 0 2px #f7f7f7  !important;
}

:deep(.n-input:focus-within) {
  background-color: #ffffff !important;
}

// :deep(.n-list-item:hover) {
//   background-color: #f7f7f7 !important;
// }



:deep(.n-layout-scroll-container) {
    overflow: hidden;
    /* 隐藏滚动条 */
    &::-webkit-scrollbar {
        width: 0; /* 将宽度设为0 */
        height: 0; /* 横向滚动条也隐藏 */
        display: none; /* 确保不显示 */
    }

    /* 其他滚动条样式设为透明 */
    &::-webkit-scrollbar-track {
        background: transparent !important;
    }

    &::-webkit-scrollbar-thumb {
        background: transparent !important;
        border-radius: 0;
    }

    /* 鼠标悬停时也不显示滚动条 */
    &:hover::-webkit-scrollbar {
        opacity: 0;
        display: none;
        width: 0;
    }

    /* 滚动条的滑块在悬停状态下的样式 */
    &::-webkit-scrollbar-thumb:hover {
        background: transparent !important;
    }
}
.scrollable-container {
    overflow-y: auto; // 添加纵向滚动条
    overflow-x: hidden; /* 隐藏水平滚动条 */
    max-height: calc(
        100vh - 120px
    ); // 设置最大高度，确保输入框和导航栏有足够的空间
    padding-bottom: 20px; // 底部内边距，防止内容被遮挡
    background-color: #f6f7fb;
    margin-right: 5px;
    
    // background: linear-gradient(to bottom, #f0effe, #f6f7fb);
}
/* 滚动条整体部分 */
::-webkit-scrollbar {
    width: 4px; /* 竖向滚动条宽度 */
    height: 4px; /* 横向滚动条高度 */
}

/* 滚动条的轨道 */
::-webkit-scrollbar-track {
    background: #fff; /* 轨道背景色 */
}

/* 滚动条的滑块 */
::-webkit-scrollbar-thumb {
    background: #cac9f9; /* 滑块颜色 */
    border-radius: 10px; /* 滑块圆角 */
}

/* 滚动条的滑块在悬停状态下的样式 */
::-webkit-scrollbar-thumb:hover {
    background: #cac9f9; /* 悬停时滑块颜色 */
}

:deep(.custom-table .n-data-table-thead) {
    display: none;
}
:deep(.custom-table td) {
    color: #26244c;
    font-size: 14px;
    // border: 0px;
    padding: 10px 6px;
    margin: 0px 0px 12px;
}
/* 添加以下样式来修改n-data-table的背景颜色 */
.tableData{
    :deep(.custom-table .n-data-table) {
    background-color: #f3f3f3 !important;
}
:deep(.custom-table .n-data-table-base-table) {
    background-color: #f3f3f3 !important;
}

:deep(.custom-table .n-data-table-tbody) {
    background-color: #f3f3f3 !important;
}

:deep(.custom-table .n-data-table-tr .n-data-table-td) {
    padding: 0 !important;
    background-color: #f3f3f3 !important;
}

}
:deep(.n-data-table .n-data-table-td){
    border-bottom:0px
}
:deep(.custom-table .n-data-table-base-table) {
    background-color: #ffffff !important;
}

:deep(.custom-table .n-data-table-tbody) {
    background-color: #ffffff !important;
}

:deep(.custom-table .n-data-table-tr .n-data-table-td) {
    padding: 0 !important;
    background-color: #ffffff !important;
}

.default-page {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh; /* 使容器高度占满整个视口 */
    background-color: #f6f7fb; /* 可选：设置背景颜色 */
}

.active-tab {
    // background: linear-gradient(to left, #f3f2ff, #e1e7fe);
    background: linear-gradient(to left, #f0effe, #d4eefc);
    border-color: #635eed;
    color: #635eed;
}

/* 新建对话框的淡入淡出动画样式 */
.fade-enter-active {
    transition: opacity 1s; /* 出现时较慢 */
}
.fade-leave-active {
    transition: opacity 0s; /* 隐藏时较快 */
}
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
    opacity: 0;
}
@keyframes spin {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

.custom-layout {
    border-top-left-radius: 10px;
    background-color: #f3f3f3;
}

.header,
.footer {
    background-color: #ffffff;
}

.content {
    flex-grow: 1; /* 占据剩余空间 */
    background-color: #ffffff;
    padding: 8px;
}
.footer {
    border-bottom-left-radius: 10px;
}

:deep(.n-layout-scroll-container) {
    overflow: hidden;
    /* 滚动条整体部分 */
    &::-webkit-scrollbar {
        width: 6px; /* 竖向滚动条宽度 */
        height: 2px; /* 横向滚动条高度 */
        opacity: 0; /* 初始时隐藏滚动条 */
        transition: opacity 0.3s; /* 添加过渡效果 */
    }

    /* 滚动条的轨道 */
    &::-webkit-scrollbar-track {
        background: #ffffff !important; /* 轨道背景色 */
    }

    /* 滚动条的滑块 */
    &::-webkit-scrollbar-thumb {
        background: #dee2ea !important; /* 滑块颜色 */
        border-radius: 10px; /* 滑块圆角 */
    }

    /* 鼠标悬停时显示滚动条 */
    &:hover::-webkit-scrollbar {
        opacity: 1; /* 显示滚动条 */
    }

    /* 滚动条的滑块在悬停状态下的样式 */
    &::-webkit-scrollbar-thumb:hover {
        background: #a48ef4 !important; /* 悬停时滑块颜色 */
    }
}

.icon-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px; /* 可根据需要调整 */
    height: 38px; /* 与宽度相同，形成圆形 */
    border-radius: 100%; /* 圆形 */
    border: 1px solid #e8eaf3;
    background-color: #ffffff; /* 按钮背景颜色 */
    cursor: pointer;
    transition: background-color 0.3s; /* 平滑过渡效果 */
    position: relative; /* 相对定位 */
}
.icon-button.selected {
    border: 1px solid #a48ef4;
}

.icon-button:hover {
    border: 1px solid #a48ef4; /* 鼠标悬停时的颜色 */
}
.icon{
        cursor: pointer;
}
:deep(.n-button__content){
    display: block;
}

:deep(.content) {
    background: #f3f3f3;
}


/* 滚动条整体部分 */
::-webkit-scrollbar {
    width: 6px; /* 竖向滚动条宽度 */
    height: 8px; /* 横向滚动条高度 */
}

/* 滚动条的轨道 */
::-webkit-scrollbar-track {
    background: #fff; /* 轨道背景色 */
}

/* 滚动条的滑块 */
::-webkit-scrollbar-thumb {
    background: #f3f3f3; /* 修改滑块颜色为 #f3f3f3 (原来是 #cac9f9) */
    border-radius: 10px; /* 滑块圆角 */
}

/* 滚动条的滑块在悬停状态下的样式 */
::-webkit-scrollbar-thumb:hover {
    background: #f3f3f3; /* 修改悬停时滑块颜色为 #f3f3f3 (原来是 #cac9f9) */
}

/* 添加选中对话项的样式 */
:deep(.selected-chat-item) {
  background-color: #e1e7fe !important;
  border-radius: 8px;
  transition: background-color 0.3s ease;
}

/* 鼠标悬停效果 */
// :deep(.n-button:hover) {
//   background-color: #f0f0f0 !important;
//   border-radius: 8px;
// }
.file-card-container {
    // position: absolute;
    top: -40%;
    left: 10px;
    width: 18% !important;
//   margin-bottom: 15px;
}

.file-card {
  display: flex;
  align-items: center;
  background-color: #f5f5f5;
  border-radius: 8px;
  padding: 12px 16px;
//   margin-bottom: 10px;
  position: relative;
  min-width: 178px;
  margin-top: 10px;
}
.file-card-preview{
    display: flex;
  align-items: center;
  background-color: #ffffff;
  border-radius: 8px;
  padding: 12px 16px;
//   margin-bottom: 10px;
  position: relative;
  min-width: 178px;
  margin-top: 10px; 
 border: 1px solid rgba(0, 0, 0, 0.08);
 cursor: pointer;
}
 .file-card-preview:hover{
    background-color: #f2f2f2;
}
.file-icon {
  margin-right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
//   background-color: #e8f5e9;
  border-radius: 6px;
}

.file-info {
  flex: 1;
}

.file-name {
    font-size: 14px;
    font-weight: 500;
    color: #333;
    white-space: nowrap;      /* 不换行 */
    overflow: hidden;         /* 隐藏溢出内容 */
    text-overflow: ellipsis;  /* 显示省略号 */
    max-width: 110px;         /* 使用max-width代替width */
    display: block;           /* 确保元素是块级元素 */
}

.file-meta {
  font-size: 12px;
  color: #999;
}

.file-close {
  position: absolute;
  top: -2px;
  right: -1px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.2s ease;
  
  &:hover {
    background-color: rgba(0, 0, 0, 0.2);
  }
}
.file-close-img{
    position: absolute;
  top: -2px;
  right: -1px;
  width: 14px;
  height: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.2s ease;
  
  &:hover {
    background-color: rgba(0, 0, 0, 0.2);
  }
}

.image-preview-list {
    position: relative;
  margin-top: 16px;
  border: 1px solid #e8e8e8;
  border-radius: 8px;
  width: 122px;
    height: 70px;
    object-fit: cover;
    border: none;
  cursor: pointer;
  &:hover {
    border-color: #dadada;
  }
}
.image-preview-list img {
    width: 100%;
    height: 100%;
    border-radius: 8px;
    object-fit: cover;
}
.image-preview {
    position: relative;
  margin-top: 16px;
  padding: 8px;
  border: 1px solid #e8e8e8;
  border-radius: 8px;
  width: 60px;
  height: 60px;
  cursor: pointer;
  &:hover {
    border-color: #dadada;
  }
}

.image-preview img {
    width: 100%;
    height: 100%;
    border-radius: 8px;
    object-fit: cover;
}
.emoji-icon {
  font-size: 28px;
  line-height: 1;
}
:deep(.n-input:hover) {
  background-color: transparent !important;
}
:deep(.n-input:focus) {
  background-color: transparent !important;
}

:deep(.n-input) {
  --n-border-hover: transparent !important;
  --n-border-focus: transparent !important;
  --n-box-shadow-focus: none !important;
}

:deep(.n-input:focus-within) {
  background-color: transparent !important;
}
/* 添加高亮样式 */
:deep(.highlight-conversation) {
  background-color: rgba(124, 58, 237, 0.1) !important;
  border-left: 3px solid #7c3aed !important;
  transition: all 0.3s ease;
}

/* 确保对话项有过渡效果 */
:deep(.custom-table tr), :deep(.conversation-item) {
  transition: background-color 0.3s ease, border-left 0.3s ease;
}

.i-carbon\:microphone,
.i-carbon\:microphone-filled {
  font-size: 20px;
}

.i-carbon\:microphone-filled {
  color: #18a058;
}
.container {
  height: 25px;
  width: 25px;
  display: flex; /* 使用flexbox布局 */
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  background: #fcfcfc;
  border: 2px solid #e9e9e9; /* 红色边框 */
  border-radius: 5px;
  cursor: pointer;
  margin: 10px;
}
.container:hover {
  background: #f2f2f2;
}

.dot {
  width: 3px; /* 点的宽度 */
  height: 3px; /* 点的高度 */
  background-color: gray; /* 点的颜色 */
  border-radius: 50%; /* 使点呈圆形 */
  margin: 5px 3px; /* 点之间的间距 */
}
.common-line{
  position: absolute;

    width: calc(100% - 20px);
    height: 24px;
    background: linear-gradient(180deg, (rgba(255, 255, 255, 0)) 0%, (#FCFCFC) 100%);
    left: 28%;
    bottom: 123px;
    transform: translateY(-100%);
    z-index: 999;
    pointer-events: none;
}
</style>
